From python-checkins at python.org Wed Jun 1 00:01:42 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 00:01:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Close_=2312229=3A_Remove_an?= =?utf8?q?_unused_argument_of_=5Fbufferedreader=5Fpeek=5Funlocked=28=29=2C?= Message-ID: http://hg.python.org/cpython/rev/549cb21a8757 changeset: 70551:549cb21a8757 user: Victor Stinner date: Wed Jun 01 00:01:24 2011 +0200 summary: Close #12229: Remove an unused argument of _bufferedreader_peek_unlocked(), io.BufferedReader._peek_unlocked(). Patch written by John O'Connor. files: Modules/_io/bufferedio.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -589,7 +589,7 @@ static void _bufferedwriter_reset_buf(buffered *self); static PyObject * -_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t); +_bufferedreader_peek_unlocked(buffered *self); static PyObject * _bufferedreader_read_all(buffered *self); static PyObject * @@ -797,7 +797,7 @@ goto end; Py_CLEAR(res); } - res = _bufferedreader_peek_unlocked(self, n); + res = _bufferedreader_peek_unlocked(self); end: LEAVE_BUFFERED(self) @@ -1611,7 +1611,7 @@ } static PyObject * -_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n) +_bufferedreader_peek_unlocked(buffered *self) { Py_ssize_t have, r; -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 00:11:25 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 00:11:25 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_disable_ASDLGEN_if_hg_won?= =?utf8?q?=27t_work=2C_or_if_python_is_not_installed=2E?= Message-ID: http://hg.python.org/cpython/rev/435eec7b41f0 changeset: 70552:435eec7b41f0 user: Ralf Schmitt date: Tue May 31 17:10:03 2011 -0500 summary: disable ASDLGEN if hg won't work, or if python is not installed. This change makes configure check for - the existence of a hg repository - the hg executable itself - the python executable Running $(srcdir)/Parser/asdl_c.py (i.e. ASDLGEN) will fail if any of the above prerequisites is missing, so we now disable it instead. closes #12225 files: Makefile.pre.in | 2 +- configure.in | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -274,7 +274,7 @@ ASDLGEN_FILES= $(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py # XXX Note that a build now requires Python exist before the build starts -ASDLGEN= $(srcdir)/Parser/asdl_c.py +ASDLGEN= @DISABLE_ASDLGEN@ $(srcdir)/Parser/asdl_c.py ########################################################################## # Python diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -811,7 +811,13 @@ AC_SUBST(HGVERSION) AC_SUBST(HGTAG) AC_SUBST(HGBRANCH) + +if test -e $srcdir/.hg/00changelog.i +then AC_CHECK_PROG(HAS_HG, hg, found, not-found) +else +HAS_HG=no-repository +fi if test $HAS_HG = found then HGVERSION="hg id -i \$(srcdir)" @@ -823,6 +829,15 @@ HGBRANCH="" fi +AC_SUBST(DISABLE_ASDLGEN) +DISABLE_ASDLGEN="" +AC_CHECK_PROG(HAS_PYTHON, python, found, not-found) +if test $HAS_HG != found -o $HAS_PYTHON != found +then + DISABLE_ASDLGEN="@echo hg: $HAS_HG, python: $HAS_PYTHON! cannot run \$(srcdir)/Parser/asdl_c.py #" +fi + + case $MACHDEP in bsdos*|hp*|HP*) # install -d does not work on BSDI or HP-UX -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 00:11:25 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 00:11:25 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_add_news_note?= Message-ID: http://hg.python.org/cpython/rev/cb2e3188832b changeset: 70553:cb2e3188832b user: Benjamin Peterson date: Tue May 31 17:11:26 2011 -0500 summary: add news note files: Misc/NEWS | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12225: Still allow Python to build if Python is not in its hg repo or + mercurial is not installed. + - Issue #1195: my_fgets() now always clears errors before calling fgets(). Fix the following case: sys.stdin.read() stopped with CTRL+d (end of file), raw_input() interrupted by CTRL+c. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 01:08:54 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 01:08:54 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogQ2xvc2UgIzEyMDg1?= =?utf8?q?=3A_Fix_an_attribute_error_in_subprocess=2EPopen_destructor_if_t?= =?utf8?q?he?= Message-ID: http://hg.python.org/cpython/rev/0f2714e49583 changeset: 70554:0f2714e49583 branch: 3.2 parent: 70541:2a313ceaf17c user: Victor Stinner date: Wed Jun 01 00:57:47 2011 +0200 summary: Close #12085: Fix an attribute error in subprocess.Popen destructor if the constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. files: Lib/subprocess.py | 5 ++++- Lib/test/test_subprocess.py | 10 ++++++++++ Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 4 files changed, 19 insertions(+), 1 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -768,7 +768,10 @@ self.wait() def __del__(self, _maxsize=sys.maxsize, _active=_active): - if not self._child_created: + # If __init__ hasn't had a chance to execute (e.g. if it + # was passed an undeclared keyword argument), we don't + # have a _child_created attribute at all. + if not getattr(self, '_child_created', False): # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -121,6 +121,16 @@ env=newenv) self.assertEqual(rc, 1) + def test_invalid_args(self): + # Popen() called with invalid arguments should raise TypeError + # but Popen.__del__ should not complain (issue #12085) + with support.captured_stderr() as s: + self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) + argcount = subprocess.Popen.__init__.__code__.co_argcount + too_many_args = [0] * (argcount + 1) + self.assertRaises(TypeError, subprocess.Popen, *too_many_args) + self.assertEqual(s.getvalue(), '') + def test_stdin_none(self): # .stdin is None when not redirected p = subprocess.Popen([sys.executable, "-c", 'print("banana")'], diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -650,6 +650,7 @@ Jason Orendorff Douglas Orr Michele Orr? +Oleg Oshmyan Denis S. Otkidach Michael Otteneder R. M. Oudkerk diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,10 @@ Library ------- +- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the + constructor has failed, e.g. because of an undeclared keyword argument. Patch + written by Oleg Oshmyan. + - Issue #985064: Make plistlib more resilient to faulty input plists. Patch by Mher Movsisyan. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 01:08:55 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 01:08:55 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_Close_=2312085=3A_Fix_an_attribute_error_i?= =?utf8?q?n_subprocess=2EPopen_destructor?= Message-ID: http://hg.python.org/cpython/rev/71dfd8cf4bf5 changeset: 70555:71dfd8cf4bf5 parent: 70553:cb2e3188832b parent: 70554:0f2714e49583 user: Victor Stinner date: Wed Jun 01 00:58:57 2011 +0200 summary: (Merge 3.2) Close #12085: Fix an attribute error in subprocess.Popen destructor if the constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. files: Lib/subprocess.py | 5 ++++- Lib/test/test_subprocess.py | 10 ++++++++++ Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 4 files changed, 19 insertions(+), 1 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -775,7 +775,10 @@ self.wait() def __del__(self, _maxsize=sys.maxsize, _active=_active): - if not self._child_created: + # If __init__ hasn't had a chance to execute (e.g. if it + # was passed an undeclared keyword argument), we don't + # have a _child_created attribute at all. + if not getattr(self, '_child_created', False): # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -146,6 +146,16 @@ env=newenv) self.assertEqual(rc, 1) + def test_invalid_args(self): + # Popen() called with invalid arguments should raise TypeError + # but Popen.__del__ should not complain (issue #12085) + with support.captured_stderr() as s: + self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) + argcount = subprocess.Popen.__init__.__code__.co_argcount + too_many_args = [0] * (argcount + 1) + self.assertRaises(TypeError, subprocess.Popen, *too_many_args) + self.assertEqual(s.getvalue(), '') + def test_stdin_none(self): # .stdin is None when not redirected p = subprocess.Popen([sys.executable, "-c", 'print("banana")'], diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -688,6 +688,7 @@ Jason Orendorff Douglas Orr Michele Orr? +Oleg Oshmyan Denis S. Otkidach Michael Otteneder R. M. Oudkerk diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -184,6 +184,10 @@ Library ------- +- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the + constructor has failed, e.g. because of an undeclared keyword argument. Patch + written by Oleg Oshmyan. + - Issue #12028: Make threading._get_ident() public, rename it to threading.get_ident() and document it. This function was already used using _thread.get_ident(). -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 01:08:56 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 01:08:56 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogQ2xvc2UgIzEyMDg1?= =?utf8?q?=3A_Fix_an_attribute_error_in_subprocess=2EPopen_destructor_if_t?= =?utf8?q?he?= Message-ID: http://hg.python.org/cpython/rev/26ea0a46aadd changeset: 70556:26ea0a46aadd branch: 2.7 parent: 70540:6c6923a406df user: Victor Stinner date: Wed Jun 01 01:03:00 2011 +0200 summary: Close #12085: Fix an attribute error in subprocess.Popen destructor if the constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. files: Lib/subprocess.py | 5 ++++- Lib/test/test_subprocess.py | 10 ++++++++++ Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 4 files changed, 19 insertions(+), 1 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -707,7 +707,10 @@ def __del__(self, _maxint=sys.maxint, _active=_active): - if not self._child_created: + # If __init__ hasn't had a chance to execute (e.g. if it + # was passed an undeclared keyword argument), we don't + # have a _child_created attribute at all. + if not getattr(self, '_child_created', False): # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -113,6 +113,16 @@ env=newenv) self.assertEqual(rc, 1) + def test_invalid_args(self): + # Popen() called with invalid arguments should raise TypeError + # but Popen.__del__ should not complain (issue #12085) + with support.captured_stderr() as s: + self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) + argcount = subprocess.Popen.__init__.__code__.co_argcount + too_many_args = [0] * (argcount + 1) + self.assertRaises(TypeError, subprocess.Popen, *too_many_args) + self.assertEqual(s.getvalue(), '') + def test_stdin_none(self): # .stdin is None when not redirected p = subprocess.Popen([sys.executable, "-c", 'print "banana"'], diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -607,6 +607,7 @@ Jason Orendorff Douglas Orr Michele Orr? +Oleg Oshmyan Denis S. Otkidach Michael Otteneder R. M. Oudkerk diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,10 @@ Library ------- +- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the + constructor has failed, e.g. because of an undeclared keyword argument. Patch + written by Oleg Oshmyan. + Tests ----- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 01:26:08 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 01:26:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_run_autoreconf?= Message-ID: http://hg.python.org/cpython/rev/4d34129dd882 changeset: 70557:4d34129dd882 parent: 70555:71dfd8cf4bf5 user: Benjamin Peterson date: Tue May 31 18:26:08 2011 -0500 summary: run autoreconf files: configure | 576 ++++++++++++++++++++++------------------- 1 files changed, 305 insertions(+), 271 deletions(-) diff --git a/configure b/configure --- a/configure +++ b/configure @@ -1,14 +1,14 @@ #! /bin/sh # From configure.in Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for python 3.3. +# Generated by GNU Autoconf 2.65 for python 3.3. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -320,7 +320,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -360,19 +360,19 @@ fi # as_fn_arith -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. +# script with status $?, using 1 if that was 0. as_fn_error () { - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi - $as_echo "$as_me: error: $2" >&2 + $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error @@ -534,7 +534,7 @@ exec 6>&1 # Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -636,6 +636,8 @@ INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +HAS_PYTHON +DISABLE_ASDLGEN HAS_HG HGBRANCH HGTAG @@ -832,9 +834,8 @@ fi case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -879,7 +880,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -905,7 +906,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1109,7 +1110,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1125,7 +1126,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1155,8 +1156,8 @@ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." ;; *=*) @@ -1164,7 +1165,7 @@ # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1182,13 +1183,13 @@ if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" + as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1211,7 +1212,7 @@ [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1225,8 +1226,8 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1241,9 +1242,9 @@ ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" + as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" + as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1282,11 +1283,11 @@ fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1326,7 +1327,7 @@ --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1511,9 +1512,9 @@ if $ac_init_version; then cat <<\_ACEOF python configure 3.3 -generated by GNU Autoconf 2.67 - -Copyright (C) 2010 Free Software Foundation, Inc. +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1629,7 +1630,7 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { + test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1653,10 +1654,10 @@ ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1692,7 +1693,7 @@ else ac_header_preproc=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -1715,15 +1716,17 @@ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## -------------------------------------- ## +( cat <<\_ASBOX +## -------------------------------------- ## ## Report this to http://bugs.python.org/ ## -## -------------------------------------- ##" +## -------------------------------------- ## +_ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -1787,7 +1790,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1818,7 +1821,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1872,7 +1875,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1902,7 +1905,8 @@ esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : + eval as_val=\$$3 + if test "x$as_val" = x""no; then : else break @@ -1925,7 +1929,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1976,7 +1980,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : + eval as_val=\$$3 + if test "x$as_val" = x""no; then : else break @@ -2176,7 +2181,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2244,7 +2249,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } -if eval "test \"\${$4+set}\"" = set; then : +if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2292,18 +2297,15 @@ } # ac_fn_c_check_member -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. +# ac_fn_c_check_decl LINENO SYMBOL VAR +# ------------------------------------ +# Tests whether SYMBOL is declared, setting cache variable VAR accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5 +$as_echo_n "checking whether $2 is declared... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2312,12 +2314,8 @@ int main () { -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif +#ifndef $2 + (void) $2; #endif ; @@ -2342,7 +2340,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by python $as_me 3.3, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2452,9 +2450,11 @@ { echo - $as_echo "## ---------------- ## + cat <<\_ASBOX +## ---------------- ## ## Cache variables. ## -## ---------------- ##" +## ---------------- ## +_ASBOX echo # The following way of writing the cache mishandles newlines in values, ( @@ -2488,9 +2488,11 @@ ) echo - $as_echo "## ----------------- ## + cat <<\_ASBOX +## ----------------- ## ## Output variables. ## -## ----------------- ##" +## ----------------- ## +_ASBOX echo for ac_var in $ac_subst_vars do @@ -2503,9 +2505,11 @@ echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + cat <<\_ASBOX +## ------------------- ## ## File substitutions. ## -## ------------------- ##" +## ------------------- ## +_ASBOX echo for ac_var in $ac_subst_files do @@ -2519,9 +2523,11 @@ fi if test -s confdefs.h; then - $as_echo "## ----------- ## + cat <<\_ASBOX +## ----------- ## ## confdefs.h. ## -## ----------- ##" +## ----------- ## +_ASBOX echo cat confdefs.h echo @@ -2576,12 +2582,7 @@ ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2596,11 +2597,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } + . "$ac_site_file" fi done @@ -2676,7 +2673,7 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2777,7 +2774,7 @@ UNIVERSALSDK=$enableval if test ! -d "${UNIVERSALSDK}" then - as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 + as_fn_error "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 fi ;; esac @@ -3169,7 +3166,7 @@ # If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then - as_fn_error $? "cached CC is different -- throw away $cache_file + as_fn_error "cached CC is different -- throw away $cache_file (it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5 fi @@ -3479,8 +3476,8 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -3594,8 +3591,9 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3637,8 +3635,8 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3695,9 +3693,9 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. +as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details." "$LINENO" 5; } fi fi fi @@ -3748,8 +3746,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -4232,7 +4230,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4248,11 +4246,11 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4291,7 +4289,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4307,18 +4305,18 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c @@ -4379,7 +4377,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP @@ -4445,7 +4443,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP @@ -4577,7 +4575,8 @@ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -5142,6 +5141,9 @@ + +if test -e $srcdir/.hg/00changelog.i +then # Extract the first word of "hg", so it can be a program name with args. set dummy hg; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -5180,6 +5182,9 @@ fi +else +HAS_HG=no-repository +fi if test $HAS_HG = found then HGVERSION="hg id -i \$(srcdir)" @@ -5191,6 +5196,52 @@ HGBRANCH="" fi + +DISABLE_ASDLGEN="" +# Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_HAS_PYTHON+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAS_PYTHON"; then + ac_cv_prog_HAS_PYTHON="$HAS_PYTHON" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_HAS_PYTHON="found" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_PYTHON" && ac_cv_prog_HAS_PYTHON="not-found" +fi +fi +HAS_PYTHON=$ac_cv_prog_HAS_PYTHON +if test -n "$HAS_PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_PYTHON" >&5 +$as_echo "$HAS_PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test $HAS_HG != found -o $HAS_PYTHON != found +then + DISABLE_ASDLGEN="@echo hg: $HAS_HG, python: $HAS_PYTHON! cannot run \$(srcdir)/Parser/asdl_c.py #" +fi + + case $MACHDEP in bsdos*|hp*|HP*) # install -d does not work on BSDI or HP-UX @@ -5201,22 +5252,16 @@ esac ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -5554,7 +5599,7 @@ ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" else - as_fn_error $? "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 + as_fn_error "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 fi @@ -6042,7 +6087,8 @@ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -6056,7 +6102,7 @@ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if eval "test \"\${$as_ac_Header+set}\"" = set; then : +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6083,7 +6129,8 @@ eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF @@ -6608,8 +6655,9 @@ if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (int) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (int) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_int=0 fi @@ -6641,8 +6689,9 @@ if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long=0 fi @@ -6674,8 +6723,9 @@ if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (void *) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_void_p=0 fi @@ -6707,8 +6757,9 @@ if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (short) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (short) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_short=0 fi @@ -6740,8 +6791,9 @@ if test "$ac_cv_type_float" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (float) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (float) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_float=0 fi @@ -6773,8 +6825,9 @@ if test "$ac_cv_type_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (double) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (double) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_double=0 fi @@ -6806,8 +6859,9 @@ if test "$ac_cv_type_fpos_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (fpos_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (fpos_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_fpos_t=0 fi @@ -6839,8 +6893,9 @@ if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (size_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (size_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_size_t=0 fi @@ -6872,8 +6927,9 @@ if test "$ac_cv_type_pid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (pid_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (pid_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_pid_t=0 fi @@ -6932,8 +6988,9 @@ if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long long) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long long) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long_long=0 fi @@ -6993,8 +7050,9 @@ if test "$ac_cv_type_long_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long double) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long double) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long_double=0 fi @@ -7055,8 +7113,9 @@ if test "$ac_cv_type__Bool" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (_Bool) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (_Bool) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof__Bool=0 fi @@ -7103,8 +7162,9 @@ if test "$ac_cv_type_uintptr_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (uintptr_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (uintptr_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_uintptr_t=0 fi @@ -7144,8 +7204,9 @@ if test "$ac_cv_type_off_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (off_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (off_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_off_t=0 fi @@ -7206,8 +7267,9 @@ if test "$ac_cv_type_time_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (time_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (time_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_time_t=0 fi @@ -7278,8 +7340,9 @@ if test "$ac_cv_type_pthread_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (pthread_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (pthread_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_pthread_t=0 fi @@ -7366,7 +7429,7 @@ MACOSX_DEFAULT_ARCH="ppc" ;; *) - as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac else @@ -7378,7 +7441,7 @@ MACOSX_DEFAULT_ARCH="ppc64" ;; *) - as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac @@ -7404,7 +7467,7 @@ $as_echo "yes" >&6; } if test $enable_shared = "yes" then - as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 + as_fn_error "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -8244,12 +8307,12 @@ withval=$with_dbmliborder; if test x$with_dbmliborder = xyes then -as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 +as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 else for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb then - as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 + as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 fi done fi @@ -9222,7 +9285,7 @@ $as_echo "#define WITH_VALGRIND 1" >>confdefs.h else - as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5 + as_fn_error "Valgrind support requested but headers not available" "$LINENO" 5 fi @@ -9321,7 +9384,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10344,7 +10408,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10353,44 +10418,25 @@ done -ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" -if test "x$ac_cv_func_dup2" = x""yes; then : - $as_echo "#define HAVE_DUP2 1" >>confdefs.h +for ac_func in dup2 getcwd strdup +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF else case " $LIBOBJS " in - *" dup2.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS dup2.$ac_objext" + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; esac fi - -ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" -if test "x$ac_cv_func_getcwd" = x""yes; then : - $as_echo "#define HAVE_GETCWD 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" getcwd.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS getcwd.$ac_objext" - ;; -esac - -fi - -ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" -if test "x$ac_cv_func_strdup" = x""yes; then : - $as_echo "#define HAVE_STRDUP 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" strdup.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strdup.$ac_objext" - ;; -esac - -fi +done for ac_func in getpgrp @@ -11603,7 +11649,7 @@ then LIBM=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 $as_echo "set LIBM=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 +else as_fn_error "proper usage is --with-libm=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 @@ -11627,7 +11673,7 @@ then LIBC=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 $as_echo "set LIBC=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 +else as_fn_error "proper usage is --with-libc=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 @@ -11877,7 +11923,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -11889,7 +11936,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -12152,7 +12200,7 @@ 15|30) ;; *) - as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; + as_fn_error "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 $as_echo "$enable_big_digits" >&6; } @@ -12203,8 +12251,9 @@ if test "$ac_cv_type_wchar_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (wchar_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (wchar_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_wchar_t=0 fi @@ -12573,8 +12622,8 @@ ;; #( *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac @@ -12835,7 +12884,7 @@ have_readline=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13009,7 +13058,7 @@ have_readline=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13931,7 +13980,6 @@ ac_libobjs= ac_ltlibobjs= -U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -14094,19 +14142,19 @@ (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. +# script with status $?, using 1 if that was 0. as_fn_error () { - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi - $as_echo "$as_me: error: $2" >&2 + $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error @@ -14302,7 +14350,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -14356,7 +14404,7 @@ # values after options handling. ac_log=" This file was extended by python $as_me 3.3, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -14418,10 +14466,10 @@ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ python config.status 3.3 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -14437,16 +14485,11 @@ while test $# != 0 do case $1 in - --*=?*) + --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; *) ac_option=$1 ac_optarg=$2 @@ -14468,7 +14511,6 @@ $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -14481,7 +14523,7 @@ ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' + as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -14490,7 +14532,7 @@ ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' + -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -14549,7 +14591,7 @@ "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -14586,7 +14628,7 @@ { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -14603,7 +14645,7 @@ fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' + ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi @@ -14617,18 +14659,18 @@ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14717,28 +14759,20 @@ else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// s/^[^=]*=[ ]*$// }' fi @@ -14766,7 +14800,7 @@ if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14851,7 +14885,7 @@ _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -14864,7 +14898,7 @@ esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -14892,7 +14926,7 @@ [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -14919,7 +14953,7 @@ case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -15050,22 +15084,22 @@ $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 +which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} +which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -15076,19 +15110,19 @@ $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 + || as_fn_error "could not create -" "$LINENO" 5 fi ;; @@ -15108,7 +15142,7 @@ ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -15129,7 +15163,7 @@ exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 + $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:01:06 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 02:01:06 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMDg1?= =?utf8?q?=3A_Fix_test=5Fsubprocess_for_my_previous_commit?= Message-ID: http://hg.python.org/cpython/rev/07b43607a905 changeset: 70558:07b43607a905 branch: 2.7 parent: 70556:26ea0a46aadd user: Victor Stinner date: Wed Jun 01 01:57:48 2011 +0200 summary: Issue #12085: Fix test_subprocess for my previous commit Replace support by test_support, and add captured_stderr() function. files: Lib/test/test_subprocess.py | 2 +- Lib/test/test_support.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -116,7 +116,7 @@ def test_invalid_args(self): # Popen() called with invalid arguments should raise TypeError # but Popen.__del__ should not complain (issue #12085) - with support.captured_stderr() as s: + with test_support.captured_stderr() as s: self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) argcount = subprocess.Popen.__init__.__code__.co_argcount too_many_args = [0] * (argcount + 1) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -833,6 +833,9 @@ """ return captured_output("stdout") +def captured_stderr(): + return captured_output("stderr") + def captured_stdin(): return captured_output("stdin") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:27 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:27 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogYWRkIDIuNy4yIGhl?= =?utf8?q?ader?= Message-ID: http://hg.python.org/cpython/rev/2d42e67dfebb changeset: 70559:2d42e67dfebb branch: 2.7 parent: 70508:f48756685406 user: Benjamin Peterson date: Tue May 31 18:44:55 2011 -0500 summary: add 2.7.2 header files: Misc/NEWS | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1,9 +1,16 @@ Python News +++++++++++ + What's New in Python 2.7.2? =========================== +*Release date: 2011-06-XX* + + +What's New in Python 2.7.2 release candidate 1? +=============================================== + *Release date: 2011-05-29* Core and Builtins -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:28 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_simply_use_the_?= =?utf8?q?Python_version_for_pyexpat=2E=5F=5Fversion=5F=5F_=2312221?= Message-ID: http://hg.python.org/cpython/rev/9c1116e582e3 changeset: 70560:9c1116e582e3 branch: 2.7 user: Benjamin Peterson date: Tue May 31 18:59:49 2011 -0500 summary: simply use the Python version for pyexpat.__version__ #12221 files: Misc/NEWS | 5 +++++ Modules/pyexpat.c | 26 +++++--------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7,6 +7,11 @@ *Release date: 2011-06-XX* +Extension Modules +----------------- + +- Issue #1221: Make pyexpat.__version__ equal to the Python version. + What's New in Python 2.7.2 release candidate 1? =============================================== diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1792,26 +1792,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyString_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1841,6 +1821,7 @@ PyObject *modelmod_name; PyObject *model_module; PyObject *sys_modules; + PyObject *version; static struct PyExpat_CAPI capi; PyObject* capi_object; @@ -1872,7 +1853,10 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); + version = PyString_FromString(PY_VERSION); + if (!version) + return; + PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:28 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:28 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_2=2E7=2E2_release_branch?= Message-ID: http://hg.python.org/cpython/rev/fe99c5b9a58d changeset: 70561:fe99c5b9a58d branch: 2.7 parent: 70556:26ea0a46aadd parent: 70560:9c1116e582e3 user: Benjamin Peterson date: Tue May 31 19:01:23 2011 -0500 summary: merge 2.7.2 release branch files: Misc/NEWS | 11 +++++++++++ Modules/pyexpat.c | 26 +++++--------------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -30,6 +30,17 @@ What's New in Python 2.7.2? =========================== +*Release date: 2011-06-XX* + +Extension Modules +----------------- + +- Issue #1221: Make pyexpat.__version__ equal to the Python version. + + +What's New in Python 2.7.2 release candidate 1? +=============================================== + *Release date: 2011-05-29* Core and Builtins diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1792,26 +1792,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyString_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1841,6 +1821,7 @@ PyObject *modelmod_name; PyObject *model_module; PyObject *sys_modules; + PyObject *version; static struct PyExpat_CAPI capi; PyObject* capi_object; @@ -1872,7 +1853,10 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); + version = PyString_FromString(PY_VERSION); + if (!version) + return; + PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:29 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:29 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_simply_use_the_?= =?utf8?q?Python_version_for_pyexpat=2E=5F=5Fversion=5F=5F_=2312221?= Message-ID: http://hg.python.org/cpython/rev/9c23efa3f5c7 changeset: 70562:9c23efa3f5c7 branch: 3.1 parent: 70505:35419f276c60 user: Benjamin Peterson date: Tue May 31 18:59:49 2011 -0500 summary: simply use the Python version for pyexpat.__version__ #12221 files: Misc/NEWS | 10 ++++++++++ Modules/pyexpat.c | 26 +++++--------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,16 @@ Python News +++++++++++ +What's New in Python 3.1.4? +=========================== + +*Release date: 2011-05-XX* + +Extension Modules +----------------- + +- Issue #12221: Replace pyexpat.__version__ with the Python version. + What's New in Python 3.1.4 release candidate 1? =============================================== diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1730,26 +1730,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyUnicode_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1790,6 +1770,7 @@ PyObject *errors_module; PyObject *modelmod_name; PyObject *model_module; + PyObject *version; PyObject *sys_modules; static struct PyExpat_CAPI capi; PyObject* capi_object; @@ -1822,7 +1803,10 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); + version = PyUnicode_FromString(PY_VERSION); + if (!version) + return; + PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:30 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:30 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1_=28=2312221=29?= Message-ID: http://hg.python.org/cpython/rev/f2f74b8d6767 changeset: 70563:f2f74b8d6767 branch: 3.2 parent: 70554:0f2714e49583 parent: 70562:9c23efa3f5c7 user: Benjamin Peterson date: Tue May 31 19:06:17 2011 -0500 summary: merge 3.1 (#12221) files: Misc/NEWS | 5 +++++ Modules/pyexpat.c | 26 +++++--------------------- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -52,6 +52,11 @@ - Issue #12065: connect_ex() on an SSL socket now returns the original errno when the socket's timeout expires (it used to return None). +Extension Modules +----------------- + +- Issue #12221: Replace pyexpat.__version__ with the Python version. + Build ----- diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1621,26 +1621,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyUnicode_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1681,6 +1661,7 @@ PyObject *errors_module; PyObject *modelmod_name; PyObject *model_module; + PyObject *version; PyObject *sys_modules; PyObject *tmpnum, *tmpstr; PyObject *codes_dict; @@ -1717,7 +1698,10 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); + version = PyUnicode_FromString(PY_VERSION); + if (!version) + return; + PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:31 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiBtZXJnZSAzLjIgKCMxMjIyMSk=?= Message-ID: http://hg.python.org/cpython/rev/d1291e048163 changeset: 70564:d1291e048163 parent: 70557:4d34129dd882 parent: 70563:f2f74b8d6767 user: Benjamin Peterson date: Tue May 31 19:07:45 2011 -0500 summary: merge 3.2 (#12221) files: Misc/NEWS | 2 ++ Modules/pyexpat.c | 26 +++++--------------------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -780,6 +780,8 @@ Extension Modules ----------------- +- Issue #12221: Replace pyexpat.__version__ with the Python version. + - Issue #12051: Fix segfault in json.dumps() while encoding highly-nested objects using the C accelerations. diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1622,26 +1622,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyUnicode_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1682,6 +1662,7 @@ PyObject *errors_module; PyObject *modelmod_name; PyObject *model_module; + PyObject *version; PyObject *sys_modules; PyObject *tmpnum, *tmpstr; PyObject *codes_dict; @@ -1718,7 +1699,10 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); + version = PyUnicode_FromString(PY_VERSION); + if (!version) + return; + PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 02:08:32 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 02:08:32 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/8919caab6995 changeset: 70565:8919caab6995 branch: 2.7 parent: 70561:fe99c5b9a58d parent: 70558:07b43607a905 user: Benjamin Peterson date: Tue May 31 19:08:12 2011 -0500 summary: merge heads files: Lib/test/test_subprocess.py | 2 +- Lib/test/test_support.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -116,7 +116,7 @@ def test_invalid_args(self): # Popen() called with invalid arguments should raise TypeError # but Popen.__del__ should not complain (issue #12085) - with support.captured_stderr() as s: + with test_support.captured_stderr() as s: self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) argcount = subprocess.Popen.__init__.__code__.co_argcount too_many_args = [0] * (argcount + 1) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -833,6 +833,9 @@ """ return captured_output("stdout") +def captured_stderr(): + return captured_output("stderr") + def captured_stdin(): return captured_output("stdin") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 03:52:20 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 03:52:20 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_=5F=5Fversion=5F=5Fs?= =?utf8?q?_dependent_on_subversion_keyword_expansion_=28closes_=2312221=29?= Message-ID: http://hg.python.org/cpython/rev/f3553d5083f8 changeset: 70566:f3553d5083f8 parent: 70564:d1291e048163 user: Benjamin Peterson date: Tue May 31 20:52:17 2011 -0500 summary: remove __version__s dependent on subversion keyword expansion (closes #12221) files: Lib/pickle.py | 2 - Lib/pydoc.py | 1 - Lib/tarfile.py | 2 - Lib/tkinter/__init__.py | 2 - Lib/xml/parsers/expat.py | 2 - Misc/NEWS | 4 + Modules/pyexpat.c | 5 - Objects/typeslots.inc | 2 +- Objects/typeslots.py | 2 +- Tools/unittestgui/unittestgui.py | 1 - configure | 128 +++++++++--------- configure.in | 45 +++--- setup.py | 2 - 13 files changed, 94 insertions(+), 104 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,8 +23,6 @@ """ -__version__ = "$Revision$" # Code version - from types import FunctionType, BuiltinFunctionType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -37,7 +37,6 @@ __author__ = "Ka-Ping Yee " __date__ = "26 February 2001" -__version__ = "$Revision$" __credits__ = """Guido van Rossum, for an excellent programming language. Tommy Burnette, the original creator of manpy. Paul Prescod, for all his work on onlinehelp. diff --git a/Lib/tarfile.py b/Lib/tarfile.py --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -29,8 +29,6 @@ """Read from and write to tar format archives. """ -__version__ = "$Revision$" - version = "0.9.0" __author__ = "Lars Gust\u00e4bel (lars at gustaebel.de)" __date__ = "$Date$" diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -30,8 +30,6 @@ tk.mainloop() """ -__version__ = "$Revision$" - import sys if sys.platform == "win32": # Attempt to configure Tcl/Tk without requiring PATH diff --git a/Lib/xml/parsers/expat.py b/Lib/xml/parsers/expat.py --- a/Lib/xml/parsers/expat.py +++ b/Lib/xml/parsers/expat.py @@ -1,6 +1,4 @@ """Interface to the Expat non-validating XML parser.""" -__version__ = '$Revision$' - import sys from pyexpat import * diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -184,6 +184,10 @@ Library ------- +- Issue #12221: Remove __version__ attributes from pyexpat, pickle, tarfile, + pydoc, tkinter, and xml.parsers.expat. This were useless version constants + left over from the Mercurial transition + - Issue #12085: Fix an attribute error in subprocess.Popen destructor if the constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1662,7 +1662,6 @@ PyObject *errors_module; PyObject *modelmod_name; PyObject *model_module; - PyObject *version; PyObject *sys_modules; PyObject *tmpnum, *tmpstr; PyObject *codes_dict; @@ -1699,10 +1698,6 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - version = PyUnicode_FromString(PY_VERSION); - if (!version) - return; - PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -1,4 +1,4 @@ -/* Generated by typeslots.py $Revision$ */ +/* Generated by typeslots.py */ 0, 0, offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), diff --git a/Objects/typeslots.py b/Objects/typeslots.py --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -3,7 +3,7 @@ import sys, re -print("/* Generated by typeslots.py $Revision$ */") +print("/* Generated by typeslots.py */") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) diff --git a/Tools/unittestgui/unittestgui.py b/Tools/unittestgui/unittestgui.py --- a/Tools/unittestgui/unittestgui.py +++ b/Tools/unittestgui/unittestgui.py @@ -28,7 +28,6 @@ """ __author__ = "Steve Purcell (stephen_purcell at yahoo.com)" -__version__ = "$Revision: 1.7 $"[11:-2] import sys import traceback diff --git a/configure b/configure --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision. +# From configure.in HGVERSION. # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.65 for python 3.3. # @@ -638,10 +638,6 @@ INSTALL_PROGRAM HAS_PYTHON DISABLE_ASDLGEN -HAS_HG -HGBRANCH -HGTAG -HGVERSION ARFLAGS AR RANLIB @@ -692,6 +688,10 @@ CONFIG_ARGS SOVERSION VERSION +HAS_HG +HGBRANCH +HGTAG +HGVERSION target_alias host_alias build_alias @@ -2687,6 +2687,66 @@ + + + + +if test -e $srcdir/.hg/00changelog.i +then +# Extract the first word of "hg", so it can be a program name with args. +set dummy hg; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_HAS_HG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAS_HG"; then + ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_HAS_HG="found" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" +fi +fi +HAS_HG=$ac_cv_prog_HAS_HG +if test -n "$HAS_HG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 +$as_echo "$HAS_HG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +else +HAS_HG=no-repository +fi +if test $HAS_HG = found +then + HGVERSION="hg id -i \$(srcdir)" + HGTAG="hg id -t \$(srcdir)" + HGBRANCH="hg id -b \$(srcdir)" +else + HGVERSION="" + HGTAG="" + HGBRANCH="" +fi + + + ac_config_headers="$ac_config_headers pyconfig.h" @@ -5139,64 +5199,6 @@ fi - - - -if test -e $srcdir/.hg/00changelog.i -then -# Extract the first word of "hg", so it can be a program name with args. -set dummy hg; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_HAS_HG+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$HAS_HG"; then - ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_HAS_HG="found" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" -fi -fi -HAS_HG=$ac_cv_prog_HAS_HG -if test -n "$HAS_HG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 -$as_echo "$HAS_HG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -else -HAS_HG=no-repository -fi -if test $HAS_HG = found -then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" -else - HGVERSION="" - HGTAG="" - HGBRANCH="" -fi - - DISABLE_ASDLGEN="" # Extract the first word of "python", so it can be a program name with args. set dummy python; ac_word=$2 diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -7,8 +7,30 @@ AC_PREREQ(2.65) -AC_REVISION($Revision$) AC_INIT(python, PYTHON_VERSION, http://bugs.python.org/) + +AC_SUBST(HGVERSION) +AC_SUBST(HGTAG) +AC_SUBST(HGBRANCH) + +if test -e $srcdir/.hg/00changelog.i +then +AC_CHECK_PROG(HAS_HG, hg, found, not-found) +else +HAS_HG=no-repository +fi +if test $HAS_HG = found +then + HGVERSION="hg id -i \$(srcdir)" + HGTAG="hg id -t \$(srcdir)" + HGBRANCH="hg id -b \$(srcdir)" +else + HGVERSION="" + HGTAG="" + HGBRANCH="" +fi + +AC_REVISION(HGVERSION) AC_CONFIG_SRCDIR([Include/object.h]) AC_CONFIG_HEADER(pyconfig.h) @@ -808,27 +830,6 @@ ARFLAGS="rc" fi -AC_SUBST(HGVERSION) -AC_SUBST(HGTAG) -AC_SUBST(HGBRANCH) - -if test -e $srcdir/.hg/00changelog.i -then -AC_CHECK_PROG(HAS_HG, hg, found, not-found) -else -HAS_HG=no-repository -fi -if test $HAS_HG = found -then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" -else - HGVERSION="" - HGTAG="" - HGBRANCH="" -fi - AC_SUBST(DISABLE_ASDLGEN) DISABLE_ASDLGEN="" AC_CHECK_PROG(HAS_PYTHON, python, found, not-found) diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,8 +1,6 @@ # Autodetecting setup.py script for building the Python extensions # -__version__ = "$Revision$" - import sys, os, imp, re, optparse from glob import glob import sysconfig -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:28:10 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:28:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_demote_this_to_?= =?utf8?q?a_note?= Message-ID: http://hg.python.org/cpython/rev/d5874854481d changeset: 70567:d5874854481d branch: 3.2 parent: 70563:f2f74b8d6767 user: Benjamin Peterson date: Tue May 31 21:27:41 2011 -0500 summary: demote this to a note files: Doc/c-api/weakref.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -55,7 +55,7 @@ Return the referenced object from a weak reference, *ref*. If the referent is no longer live, returns :const:`Py_None`. - .. warning:: + .. note:: This function returns a **borrowed reference** to the referenced object. This means that you should always call :c:func:`Py_INCREF` on the object -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:28:11 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:28:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/6035962e2cb0 changeset: 70568:6035962e2cb0 parent: 70566:f3553d5083f8 parent: 70567:d5874854481d user: Benjamin Peterson date: Tue May 31 21:28:03 2011 -0500 summary: merge 3.2 files: Doc/c-api/weakref.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -55,7 +55,7 @@ Return the referenced object from a weak reference, *ref*. If the referent is no longer live, returns :const:`Py_None`. - .. warning:: + .. note:: This function returns a **borrowed reference** to the referenced object. This means that you should always call :c:func:`Py_INCREF` on the object -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:32:06 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:32:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_be_extra_carefu?= =?utf8?q?l_with_a_borrowed_reference_when_the_GIL_could_be_released?= Message-ID: http://hg.python.org/cpython/rev/a856be6688a6 changeset: 70569:a856be6688a6 branch: 3.2 parent: 70567:d5874854481d user: Benjamin Peterson date: Tue May 31 21:31:37 2011 -0500 summary: be extra careful with a borrowed reference when the GIL could be released (closes #8578) files: Modules/_sqlite/connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -200,11 +200,13 @@ weakref = PyList_GetItem(self->statements, i); statement = PyWeakref_GetObject(weakref); if (statement != Py_None) { + Py_INCREF(statement); if (action == ACTION_RESET) { (void)pysqlite_statement_reset((pysqlite_Statement*)statement); } else { (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); } + Py_DECREF(statement); } } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:32:06 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:32:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/f33e21c51307 changeset: 70570:f33e21c51307 parent: 70568:6035962e2cb0 parent: 70569:a856be6688a6 user: Benjamin Peterson date: Tue May 31 21:31:59 2011 -0500 summary: merge 3.2 files: Modules/_sqlite/connection.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -200,11 +200,13 @@ weakref = PyList_GetItem(self->statements, i); statement = PyWeakref_GetObject(weakref); if (statement != Py_None) { + Py_INCREF(statement); if (action == ACTION_RESET) { (void)pysqlite_statement_reset((pysqlite_Statement*)statement); } else { (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); } + Py_DECREF(statement); } } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:39:58 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:39:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_return_NULL_on_?= =?utf8?q?error?= Message-ID: http://hg.python.org/cpython/rev/0639e630426c changeset: 70571:0639e630426c branch: 3.1 parent: 70562:9c23efa3f5c7 user: Benjamin Peterson date: Tue May 31 21:38:15 2011 -0500 summary: return NULL on error files: Modules/pyexpat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1805,7 +1805,7 @@ version = PyUnicode_FromString(PY_VERSION); if (!version) - return; + return NULL; PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:39:58 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:39:58 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1?= Message-ID: http://hg.python.org/cpython/rev/fe610255861d changeset: 70572:fe610255861d branch: 3.2 parent: 70569:a856be6688a6 parent: 70571:0639e630426c user: Benjamin Peterson date: Tue May 31 21:38:49 2011 -0500 summary: merge 3.1 files: Modules/pyexpat.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1700,7 +1700,7 @@ version = PyUnicode_FromString(PY_VERSION); if (!version) - return; + return NULL; PyModule_AddObject(m, "__version__", version); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 04:39:59 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 01 Jun 2011 04:39:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/302424b84b07 changeset: 70573:302424b84b07 parent: 70570:f33e21c51307 parent: 70572:fe610255861d user: Benjamin Peterson date: Tue May 31 21:39:38 2011 -0500 summary: merge 3.2 files: -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Wed Jun 1 05:06:13 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 01 Jun 2011 05:06:13 +0200 Subject: [Python-checkins] Daily reference leaks (d1291e048163): sum=722 Message-ID: results for d1291e048163 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 test_pydoc leaked [323, 0, 0] references, sum=323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogGkSmJ0', '-x'] From python-checkins at python.org Wed Jun 1 12:28:38 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 12:28:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_test=2Esupport=3A_add_requi?= =?utf8?q?res=5Fmac=5Fver=28=29_function?= Message-ID: http://hg.python.org/cpython/rev/35212b113730 changeset: 70574:35212b113730 user: Victor Stinner date: Wed Jun 01 12:28:04 2011 +0200 summary: test.support: add requires_mac_ver() function Add also linux_version() to __all__. files: Lib/test/support.py | 22 +++++++++++++++++++++- Lib/test/test_math.py | 7 ++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -37,7 +37,8 @@ "Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", "get_original_stdout", "unload", "unlink", "rmtree", "forget", - "is_resource_enabled", "requires", "find_unused_port", "bind_port", + "is_resource_enabled", "requires", "linux_version", "requires_mac_ver", + "find_unused_port", "bind_port", "IPV6_ENABLED", "is_jython", "TESTFN", "HOST", "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error", "open_urlresource", "check_warnings", "CleanImport", "EnvironmentVarGuard", "TransientResource", @@ -299,6 +300,25 @@ except ValueError: return 0, 0, 0 +def requires_mac_ver(*min_version): + """Raise SkipTest if the OS is Mac OS X and the OS X version if less than + min_version. + + For example, support.requires_linux_version(10, 5) raises SkipTest if the + version is less than 10.5. + """ + if sys.platform != 'darwin': + return + version_txt = platform.mac_ver()[0] + try: + version = tuple(map(int, version_txt.split('.'))) + except ValueError: + return + if version < min_version: + min_version_txt = '.'.join(map(str, min_version)) + raise unittest.SkipTest("Mac OS X %s or higher required, not %s" + % (min_version_txt, version_txt)) + HOST = 'localhost' def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2,6 +2,7 @@ # XXXX Should not do tests around zero only from test.support import run_unittest, verbose, requires_IEEE_754 +from test import support import unittest import math import os @@ -669,10 +670,10 @@ self.assertTrue(math.isnan(math.log2(NAN))) @requires_IEEE_754 - @unittest.skipIf(sys.platform == 'darwin' - and platform.mac_ver()[0].startswith('10.4.'), - 'Mac OS X Tiger log2() is not accurate enough') def testLog2Exact(self): + # log2() is not accurate enough on Mac OS X Tiger (10.4) + support.requires_mac_ver(10, 5) + # Check that we get exact equality for log2 of powers of 2. actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] expected = [float(n) for n in range(-1074, 1024)] -- Repository URL: http://hg.python.org/cpython From ezio.melotti at gmail.com Wed Jun 1 12:37:09 2011 From: ezio.melotti at gmail.com (Ezio Melotti) Date: Wed, 01 Jun 2011 13:37:09 +0300 Subject: [Python-checkins] cpython: test.support: add requires_mac_ver() function In-Reply-To: References: Message-ID: <4DE61655.5000401@gmail.com> Hi, On 01/06/2011 13.28, victor.stinner wrote: > http://hg.python.org/cpython/rev/35212b113730 > changeset: 70574:35212b113730 > user: Victor Stinner > date: Wed Jun 01 12:28:04 2011 +0200 > summary: > test.support: add requires_mac_ver() function I would expect this to be a decorator, similar to requires_IEEE_754 and requires_zlib. > Add also linux_version() to __all__. For consistency, this should be a decorator too, possibly named requires_linux_ver(). A requires_windows(_ver) sounds like a useful addition too, given the number of tests that are specific to Windows. > files: > Lib/test/support.py | 22 +++++++++++++++++++++- > Lib/test/test_math.py | 7 ++++--- > 2 files changed, 25 insertions(+), 4 deletions(-) > > > diff --git a/Lib/test/support.py b/Lib/test/support.py > --- a/Lib/test/support.py > +++ b/Lib/test/support.py > @@ -37,7 +37,8 @@ > "Error", "TestFailed", "ResourceDenied", "import_module", > "verbose", "use_resources", "max_memuse", "record_original_stdout", > "get_original_stdout", "unload", "unlink", "rmtree", "forget", > - "is_resource_enabled", "requires", "find_unused_port", "bind_port", > + "is_resource_enabled", "requires", "linux_version", "requires_mac_ver", > + "find_unused_port", "bind_port", > "IPV6_ENABLED", "is_jython", "TESTFN", "HOST", "SAVEDCWD", "temp_cwd", > "findfile", "sortdict", "check_syntax_error", "open_urlresource", > "check_warnings", "CleanImport", "EnvironmentVarGuard", "TransientResource", > @@ -299,6 +300,25 @@ > except ValueError: > return 0, 0, 0 > > +def requires_mac_ver(*min_version): > + """Raise SkipTest if the OS is Mac OS X and the OS X version if less than > + min_version. > + > + For example, support.requires_linux_version(10, 5) raises SkipTest if the This should be requires_mac_ver > + version is less than 10.5. > + """ > + if sys.platform != 'darwin': > + return > + version_txt = platform.mac_ver()[0] > + try: > + version = tuple(map(int, version_txt.split('.'))) > + except ValueError: > + return > + if version< min_version: > + min_version_txt = '.'.join(map(str, min_version)) > + raise unittest.SkipTest("Mac OS X %s or higher required, not %s" > + % (min_version_txt, version_txt)) > + > HOST = 'localhost' > > def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): > diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py > --- a/Lib/test/test_math.py > +++ b/Lib/test/test_math.py > @@ -2,6 +2,7 @@ > # XXXX Should not do tests around zero only > > from test.support import run_unittest, verbose, requires_IEEE_754 > +from test import support > import unittest > import math > import os > @@ -669,10 +670,10 @@ > self.assertTrue(math.isnan(math.log2(NAN))) > > @requires_IEEE_754 > - @unittest.skipIf(sys.platform == 'darwin' > - and platform.mac_ver()[0].startswith('10.4.'), > - 'Mac OS X Tiger log2() is not accurate enough') > def testLog2Exact(self): > + # log2() is not accurate enough on Mac OS X Tiger (10.4) > + support.requires_mac_ver(10, 5) > + > # Check that we get exact equality for log2 of powers of 2. > actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] > expected = [float(n) for n in range(-1074, 1024)] > Best Regards, Ezio Melotti From python-checkins at python.org Wed Jun 1 13:19:47 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 13:19:47 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogQ2xvc2UgIzEyMjMw?= =?utf8?q?=3A_Mac_OS_X_Tiger_=2810=2E4=29_has_a_kernel_bug=3A_sometimes=2C?= =?utf8?q?_the_file?= Message-ID: http://hg.python.org/cpython/rev/22457ac2c2df changeset: 70575:22457ac2c2df branch: 3.2 parent: 70572:fe610255861d user: Victor Stinner date: Wed Jun 01 13:13:04 2011 +0200 summary: Close #12230: Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file descriptor of a pipe closed in the parent process is valid in the child process according to fstat(), but the mode of the file descriptor is invalid, and read or write raise an error. Add also requires_mac_ver() decorator to test.support. files: Lib/test/support.py | 30 ++++++++++++++++++++++++- Lib/test/test_subprocess.py | 5 ++++ 2 files changed, 34 insertions(+), 1 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -32,7 +32,8 @@ "Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", "get_original_stdout", "unload", "unlink", "rmtree", "forget", - "is_resource_enabled", "requires", "find_unused_port", "bind_port", + "is_resource_enabled", "requires", "requires_mac_ver", + "find_unused_port", "bind_port", "fcmp", "is_jython", "TESTFN", "HOST", "FUZZ", "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error", "open_urlresource", "check_warnings", "CleanImport", "EnvironmentVarGuard", @@ -288,6 +289,33 @@ msg = "Use of the `%s' resource not enabled" % resource raise ResourceDenied(msg) +def requires_mac_ver(*min_version): + """Decorator raising SkipTest if the OS is Mac OS X and the OS X + version if less than min_version. + + For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version + is lesser than 10.5. + """ + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kw): + if sys.platform == 'darwin': + version_txt = platform.mac_ver()[0] + try: + version = tuple(map(int, version_txt.split('.'))) + except ValueError: + pass + else: + if version < min_version: + min_version_txt = '.'.join(map(str, min_version)) + raise unittest.SkipTest( + "Mac OS X %s or higher required, not %s" + % (min_version_txt, version_txt)) + return func(*args, **kw) + wrapper.min_version = min_version + return wrapper + return decorator + HOST = 'localhost' def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1185,6 +1185,11 @@ "Some fds were left open") self.assertIn(1, remaining_fds, "Subprocess failed") + # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file + # descriptor of a pipe closed in the parent process is valid in the + # child process according to fstat(), but the mode of the file + # descriptor is invalid, and read or write raise an error. + @support.requires_mac_ver(10, 5) def test_pass_fds(self): fd_status = support.findfile("fd_status.py", subdir="subprocessdata") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 13:19:48 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 13:19:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_Close_=2312230=3A_Mac_OS_X_Tiger_=2810=2E4?= =?utf8?q?=29_has_a_kernel_bug=3A_sometimes=2C?= Message-ID: http://hg.python.org/cpython/rev/566c42b0e750 changeset: 70576:566c42b0e750 parent: 70574:35212b113730 parent: 70575:22457ac2c2df user: Victor Stinner date: Wed Jun 01 13:19:07 2011 +0200 summary: (Merge 3.2) Close #12230: Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file descriptor of a pipe closed in the parent process is valid in the child process according to fstat(), but the mode of the file descriptor is invalid, and read or write raise an error. test.support.requires_mac_ver() is now a decorator, as suggested by Ezio Melotti, and its docstring is fixed (linux_version => mac_ver). files: Lib/test/support.py | 39 +++++++++++++++--------- Lib/test/test_math.py | 5 +- Lib/test/test_subprocess.py | 5 +++ 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -301,23 +301,32 @@ return 0, 0, 0 def requires_mac_ver(*min_version): - """Raise SkipTest if the OS is Mac OS X and the OS X version if less than - min_version. + """Decorator raising SkipTest if the OS is Mac OS X and the OS X + version if less than min_version. - For example, support.requires_linux_version(10, 5) raises SkipTest if the - version is less than 10.5. + For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version + is lesser than 10.5. """ - if sys.platform != 'darwin': - return - version_txt = platform.mac_ver()[0] - try: - version = tuple(map(int, version_txt.split('.'))) - except ValueError: - return - if version < min_version: - min_version_txt = '.'.join(map(str, min_version)) - raise unittest.SkipTest("Mac OS X %s or higher required, not %s" - % (min_version_txt, version_txt)) + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kw): + if sys.platform == 'darwin': + version_txt = platform.mac_ver()[0] + try: + version = tuple(map(int, version_txt.split('.'))) + except ValueError: + pass + else: + if version < min_version: + min_version_txt = '.'.join(map(str, min_version)) + raise unittest.SkipTest( + "Mac OS X %s or higher required, not %s" + % (min_version_txt, version_txt)) + return func(*args, **kw) + wrapper.min_version = min_version + return wrapper + return decorator + HOST = 'localhost' diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -670,10 +670,9 @@ self.assertTrue(math.isnan(math.log2(NAN))) @requires_IEEE_754 + # log2() is not accurate enough on Mac OS X Tiger (10.4) + @support.requires_mac_ver(10, 5) def testLog2Exact(self): - # log2() is not accurate enough on Mac OS X Tiger (10.4) - support.requires_mac_ver(10, 5) - # Check that we get exact equality for log2 of powers of 2. actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] expected = [float(n) for n in range(-1074, 1024)] diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1281,6 +1281,11 @@ "Some fds were left open") self.assertIn(1, remaining_fds, "Subprocess failed") + # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file + # descriptor of a pipe closed in the parent process is valid in the + # child process according to fstat(), but the mode of the file + # descriptor is invalid, and read or write raise an error. + @support.requires_mac_ver(10, 5) def test_pass_fds(self): fd_status = support.findfile("fd_status.py", subdir="subprocessdata") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 13:49:29 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 01 Jun 2011 13:49:29 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_test=5Ffaulthandler=3A_use_?= =?utf8?q?a_longer_sleep_=282=2E5_sec_instead_of_1=2E3_sec=29_in?= Message-ID: http://hg.python.org/cpython/rev/e064191a3876 changeset: 70577:e064191a3876 user: Victor Stinner date: Wed Jun 01 13:49:12 2011 +0200 summary: test_faulthandler: use a longer sleep (2.5 sec instead of 1.3 sec) in _check_dump_tracebacks_later() to avoid failures if the system is slow. files: Lib/test/test_faulthandler.py | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -29,13 +29,14 @@ except (ValueError, resource_error): pass -def expected_traceback(lineno1, lineno2, header, count=1): +def expected_traceback(lineno1, lineno2, header, min_count=1): regex = header regex += ' File "", line %s in func\n' % lineno1 regex += ' File "", line %s in ' % lineno2 - if count != 1: - regex = (regex + '\n') * (count - 1) + regex - return '^' + regex + '$' + if 1 < min_count: + return '^' + (regex + '\n') * (min_count - 1) + regex + else: + return '^' + regex + '$' @contextmanager def temporary_filename(): @@ -371,7 +372,7 @@ faulthandler.dump_tracebacks_later(timeout, repeat=repeat, file=file) if cancel: faulthandler.cancel_dump_tracebacks_later() - time.sleep(timeout * 2.5) + time.sleep(timeout * 5) faulthandler.cancel_dump_tracebacks_later() timeout = {timeout} @@ -402,7 +403,7 @@ if repeat: count *= 2 header = r'Timeout \(%s\)!\nThread 0x[0-9a-f]+:\n' % timeout_str - regex = expected_traceback(9, 20, header, count=count) + regex = expected_traceback(9, 20, header, min_count=count) self.assertRegex(trace, regex) else: self.assertEqual(trace, '') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:29:58 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:29:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_error_messa?= =?utf8?q?ge_to_use_the_Python_name_instead_of_the_C_name?= Message-ID: http://hg.python.org/cpython/rev/7d3e0a0b0b8f changeset: 70578:7d3e0a0b0b8f branch: 2.7 parent: 70509:439396b06416 user: ?ric Araujo date: Tue May 31 14:08:40 2011 +0200 summary: Fix error message to use the Python name instead of the C name files: Modules/threadmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c --- a/Modules/threadmodule.c +++ b/Modules/threadmodule.c @@ -715,7 +715,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:29:59 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:29:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_markup=3A_a?= =?utf8?q?rguments_in_a_class_directive_are_=5F=5Finit=5F=5F_arguments=2C_?= =?utf8?q?not_base?= Message-ID: http://hg.python.org/cpython/rev/d4ae796efebb changeset: 70579:d4ae796efebb branch: 2.7 user: ?ric Araujo date: Tue May 31 21:50:22 2011 +0200 summary: Fix markup: arguments in a class directive are __init__ arguments, not base classes files: Doc/distutils/apiref.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1815,7 +1815,7 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file -.. class:: bdist_msi(Command) +.. class:: bdist_msi Builds a `Windows Installer`_ (.msi) binary package. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:30:00 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:30:00 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/3e445ceee4f5 changeset: 70580:3e445ceee4f5 branch: 2.7 parent: 70565:8919caab6995 parent: 70579:d4ae796efebb user: ?ric Araujo date: Wed Jun 01 19:28:26 2011 +0200 summary: Branch merge files: Doc/distutils/apiref.rst | 2 +- Modules/threadmodule.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1815,7 +1815,7 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file -.. class:: bdist_msi(Command) +.. class:: bdist_msi Builds a `Windows Installer`_ (.msi) binary package. diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c --- a/Modules/threadmodule.c +++ b/Modules/threadmodule.c @@ -715,7 +715,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:41:47 2011 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Jun 2011 19:41:47 +0200 (CEST) Subject: [Python-checkins] r88847 - tracker/instances/python-dev/html/issue.item.js Message-ID: <3QkzWv65W6z7LlC@mail.python.org> Author: ezio.melotti Date: Wed Jun 1 19:41:47 2011 New Revision: 88847 Log: #401/#312: revert the "Show/Hide history" addition and tweak the "end" key to jump to the last message when hit the first time instead. Modified: tracker/instances/python-dev/html/issue.item.js Modified: tracker/instances/python-dev/html/issue.item.js ============================================================================== --- tracker/instances/python-dev/html/issue.item.js (original) +++ tracker/instances/python-dev/html/issue.item.js Wed Jun 1 19:41:47 2011 @@ -42,16 +42,22 @@ nosy.style.width = new_width + "px"; } + $(document).ready(function() { - /* Add a "Show/Hide history" button that (un)folds the history. See #401 */ - var th = $('Show History'); - th.css({'cursor': 'pointer', 'text-align': 'center', - 'border': '1px solid #ccc'}); - /* select and hide all the tr except the first one ("History") */ - $('table.history tr:not(:first-child)').toggle(); - th.click(function() { - $('table.history tr:not(:first-child):not(#togglehistory)').toggle(); - th.text(th.text() == 'Show History' ? 'Hide History' : 'Show History'); + /* When the user hits the 'end' key the first time, jump to the last + message rather than to the end of the page. After that restore the + normal 'end' behavior. */ + // get the offset to the last message + var offset = $('table.messages tr th a:last').offset() + $(document).keydown(function (event) { + var node = event.target.nodeName; + // 35 == end key. Don't do anything if the focus is on form elements + if ((event.keyCode == 35) && (node != 'TEXTAREA') + && (node != 'INPUT') && (node != 'SELECT')) { + // jump at the last message and restore the usual behavior + window.scrollTo(offset.left, offset.top); + $(document).unbind('keydown') + return false; + } }); - $('table.history').append(th.wrap('').parent()); }) From python-checkins at python.org Wed Jun 1 19:47:48 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_error_messa?= =?utf8?q?ge_to_use_the_Python_name_instead_of_the_C_name?= Message-ID: http://hg.python.org/cpython/rev/26e25dc1354e changeset: 70581:26e25dc1354e branch: 3.2 parent: 70506:85f4b38a61fa user: ?ric Araujo date: Tue May 31 14:08:26 2011 +0200 summary: Fix error message to use the Python name instead of the C name files: Modules/_threadmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1091,7 +1091,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:49 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_test_name_in_debug_mess?= =?utf8?q?age?= Message-ID: http://hg.python.org/cpython/rev/f03ee0cdd8aa changeset: 70582:f03ee0cdd8aa parent: 70520:fedb33e2bf77 user: ?ric Araujo date: Tue May 31 14:33:32 2011 +0200 summary: Fix test name in debug message files: Lib/packaging/tests/test_command_build_ext.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -370,8 +370,8 @@ src = _get_source_filename() if not os.path.exists(src): if verbose: - print ('test_build_ext: Cannot find source code (test' - ' must run in python build dir)') + print('test_command_build_ext: Cannot find source code (test' + ' must run in python build dir)') return unittest.TestSuite() else: return unittest.makeSuite(BuildExtTestCase) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:50 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_nonsensical_name=2E?= Message-ID: http://hg.python.org/cpython/rev/9cc3429204cd changeset: 70583:9cc3429204cd user: ?ric Araujo date: Tue May 31 15:05:38 2011 +0200 summary: Fix nonsensical name. The code used ?long? to refer to a long option (e.g. --quiet), which was probably changed by 2to3 and not caught by the human operator, and then changed to ?integer? by me to avoid shadowing without seeing the real obvious fix. files: Lib/packaging/fancy_getopt.py | 56 +++++++++++----------- 1 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Lib/packaging/fancy_getopt.py b/Lib/packaging/fancy_getopt.py --- a/Lib/packaging/fancy_getopt.py +++ b/Lib/packaging/fancy_getopt.py @@ -142,20 +142,20 @@ for option in self.option_table: if len(option) == 3: - integer, short, help = option + longopt, short, help = option repeat = 0 elif len(option) == 4: - integer, short, help, repeat = option + longopt, short, help, repeat = option else: # the option table is part of the code, so simply # assert that it is correct raise ValueError("invalid option tuple: %r" % option) # Type- and value-check the option names - if not isinstance(integer, str) or len(integer) < 2: + if not isinstance(longopt, str) or len(longopt) < 2: raise PackagingGetoptError( ("invalid long option '%s': " - "must be a string of length >= 2") % integer) + "must be a string of length >= 2") % longopt) if (not ((short is None) or (isinstance(short, str) and len(short) == 1))): @@ -163,55 +163,55 @@ ("invalid short option '%s': " "must be a single character or None") % short) - self.repeat[integer] = repeat - self.long_opts.append(integer) + self.repeat[longopt] = repeat + self.long_opts.append(longopt) - if integer[-1] == '=': # option takes an argument? + if longopt[-1] == '=': # option takes an argument? if short: short = short + ':' - integer = integer[0:-1] - self.takes_arg[integer] = 1 + longopt = longopt[0:-1] + self.takes_arg[longopt] = 1 else: # Is option is a "negative alias" for some other option (eg. # "quiet" == "!verbose")? - alias_to = self.negative_alias.get(integer) + alias_to = self.negative_alias.get(longopt) if alias_to is not None: if self.takes_arg[alias_to]: raise PackagingGetoptError( ("invalid negative alias '%s': " "aliased option '%s' takes a value") % \ - (integer, alias_to)) + (longopt, alias_to)) - self.long_opts[-1] = integer # XXX redundant?! - self.takes_arg[integer] = 0 + self.long_opts[-1] = longopt # XXX redundant?! + self.takes_arg[longopt] = 0 else: - self.takes_arg[integer] = 0 + self.takes_arg[longopt] = 0 # If this is an alias option, make sure its "takes arg" flag is # the same as the option it's aliased to. - alias_to = self.alias.get(integer) + alias_to = self.alias.get(longopt) if alias_to is not None: - if self.takes_arg[integer] != self.takes_arg[alias_to]: + if self.takes_arg[longopt] != self.takes_arg[alias_to]: raise PackagingGetoptError( ("invalid alias '%s': inconsistent with " "aliased option '%s' (one of them takes a value, " - "the other doesn't") % (integer, alias_to)) + "the other doesn't") % (longopt, alias_to)) # Now enforce some bondage on the long option name, so we can # later translate it to an attribute name on some object. Have # to do this a bit late to make sure we've removed any trailing # '='. - if not longopt_re.match(integer): + if not longopt_re.match(longopt): raise PackagingGetoptError( ("invalid long option name '%s' " + - "(must be letters, numbers, hyphens only") % integer) + "(must be letters, numbers, hyphens only") % longopt) - self.attr_name[integer] = integer.replace('-', '_') + self.attr_name[longopt] = longopt.replace('-', '_') if short: self.short_opts.append(short) - self.short2long[short[0]] = integer + self.short2long[short[0]] = longopt def getopt(self, args=None, object=None): """Parse command-line options in args. Store as attributes on object. @@ -297,10 +297,10 @@ # First pass: determine maximum length of long option names max_opt = 0 for option in self.option_table: - integer = option[0] + longopt = option[0] short = option[1] - l = len(integer) - if integer[-1] == '=': + l = len(longopt) + if longopt[-1] == '=': l = l - 1 if short is not None: l = l + 5 # " (-x)" where short == 'x' @@ -340,20 +340,20 @@ lines = ['Option summary:'] for option in self.option_table: - integer, short, help = option[:3] + longopt, short, help = option[:3] text = textwrap.wrap(help, text_width) # Case 1: no short option at all (makes life easy) if short is None: if text: - lines.append(" --%-*s %s" % (max_opt, integer, text[0])) + lines.append(" --%-*s %s" % (max_opt, longopt, text[0])) else: - lines.append(" --%-*s " % (max_opt, integer)) + lines.append(" --%-*s " % (max_opt, longopt)) # Case 2: we have a short option, so we have to include it # just after the long option else: - opt_names = "%s (-%s)" % (integer, short) + opt_names = "%s (-%s)" % (longopt, short) if text: lines.append(" --%-*s %s" % (max_opt, opt_names, text[0])) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:51 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Re-apply_distutils2_changes?= =?utf8?q?_lost_before_the_merge_of_packaging=2E?= Message-ID: http://hg.python.org/cpython/rev/dece7112b286 changeset: 70584:dece7112b286 user: ?ric Araujo date: Tue May 31 18:04:32 2011 +0200 summary: Re-apply distutils2 changes lost before the merge of packaging. wrap_text was removed in favor of standard textwrap but the removal of the function was lost in a bad merge; a change in sdist mysteriously disappeared. files: Lib/packaging/command/sdist.py | 36 +----- Lib/packaging/fancy_getopt.py | 63 ----------- Lib/packaging/tests/test_command_sdist.py | 9 +- 3 files changed, 6 insertions(+), 102 deletions(-) diff --git a/Lib/packaging/command/sdist.py b/Lib/packaging/command/sdist.py --- a/Lib/packaging/command/sdist.py +++ b/Lib/packaging/command/sdist.py @@ -1,10 +1,9 @@ """Create a source distribution.""" import os +import re import sys -import re from io import StringIO -from glob import glob from shutil import get_archive_formats, rmtree from packaging import logger @@ -203,45 +202,14 @@ def add_defaults(self): """Add all the default files to self.filelist: - - README or README.txt - - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) - Warns if (README or README.txt) or setup.py are missing; everything - else is optional. + Everything is optional. """ - standards = [('README', 'README.txt')] - for fn in standards: - if isinstance(fn, tuple): - alts = fn - got_it = False - for fn in alts: - if os.path.exists(fn): - got_it = True - self.filelist.append(fn) - break - - if not got_it: - logger.warning( - '%s: standard file not found: should have one of %s', - self.get_command_name(), ', '.join(alts)) - else: - if os.path.exists(fn): - self.filelist.append(fn) - else: - logger.warning('%s: standard file %r not found', - self.get_command_name(), fn) - - optional = ['test/test*.py', 'setup.cfg'] - for pattern in optional: - files = [f for f in glob(pattern) if os.path.isfile(f)] - if files: - self.filelist.extend(files) - for cmd_name in get_command_names(): try: cmd_obj = self.get_finalized_command(cmd_name) diff --git a/Lib/packaging/fancy_getopt.py b/Lib/packaging/fancy_getopt.py --- a/Lib/packaging/fancy_getopt.py +++ b/Lib/packaging/fancy_getopt.py @@ -13,7 +13,6 @@ import getopt import re import sys -import string import textwrap from packaging.errors import PackagingGetoptError, PackagingArgError @@ -378,68 +377,6 @@ return parser.getopt(args, object) -WS_TRANS = str.maketrans(string.whitespace, ' ' * len(string.whitespace)) - - -def wrap_text(text, width): - """Split *text* into lines of no more than *width* characters each. - - *text* is a str and *width* an int. Returns a list of str. - """ - - if text is None: - return [] - if len(text) <= width: - return [text] - - text = text.expandtabs() - text = text.translate(WS_TRANS) - - chunks = re.split(r'( +|-+)', text) - chunks = [_f for _f in chunks if _f] # ' - ' results in empty strings - lines = [] - - while chunks: - - cur_line = [] # list of chunks (to-be-joined) - cur_len = 0 # length of current line - - while chunks: - l = len(chunks[0]) - if cur_len + l <= width: # can squeeze (at least) this chunk in - cur_line.append(chunks[0]) - del chunks[0] - cur_len = cur_len + l - else: # this line is full - # drop last chunk if all space - if cur_line and cur_line[-1][0] == ' ': - del cur_line[-1] - break - - if chunks: # any chunks left to process? - - # if the current line is still empty, then we had a single - # chunk that's too big too fit on a line -- so we break - # down and break it up at the line width - if cur_len == 0: - cur_line.append(chunks[0][0:width]) - chunks[0] = chunks[0][width:] - - # all-whitespace chunks at the end of a line can be discarded - # (and we know from the re.split above that if a chunk has - # *any* whitespace, it is *all* whitespace) - if chunks[0][0] == ' ': - del chunks[0] - - # and store this line in the list-of-all-lines -- as a single - # string, of course! - lines.append(''.join(cur_line)) - - # while chunks - - return lines - - class OptionDummy: """Dummy class just used as a place to hold command-line option values as instance attributes.""" diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -33,7 +33,6 @@ MANIFEST = """\ # file GENERATED by packaging, do NOT edit -README inroot.txt data%(sep)sdata.dt scripts%(sep)sscript.py @@ -129,7 +128,7 @@ content = zip_file.namelist() # making sure everything has been pruned correctly - self.assertEqual(len(content), 3) + self.assertEqual(len(content), 2) @requires_zlib @unittest.skipIf(find_executable('tar') is None or @@ -214,7 +213,7 @@ # Making sure everything was added. This includes 9 code and data # files in addition to PKG-INFO. - self.assertEqual(len(content), 10) + self.assertEqual(len(content), 9) # Checking the MANIFEST with open(join(self.tmp_dir, 'MANIFEST')) as fp: @@ -331,7 +330,7 @@ with open(cmd.manifest) as f: manifest = [line.strip() for line in f.read().split('\n') if line.strip() != ''] - self.assertEqual(len(manifest), 4) + self.assertEqual(len(manifest), 3) # Adding a file self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') @@ -348,7 +347,7 @@ if line.strip() != ''] # Do we have the new file in MANIFEST? - self.assertEqual(len(manifest2), 5) + self.assertEqual(len(manifest2), 4) self.assertIn('doc2.txt', manifest2[-1]) @requires_zlib -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:51 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Re-add_line_that_was_mistak?= =?utf8?q?enly_removed_alongside_RPM_support=2E?= Message-ID: http://hg.python.org/cpython/rev/4c00c82efb4a changeset: 70585:4c00c82efb4a user: ?ric Araujo date: Tue May 31 22:38:41 2011 +0200 summary: Re-add line that was mistakenly removed alongside RPM support. This reveals the need for bdist* tests. files: Lib/packaging/command/bdist.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Lib/packaging/command/bdist.py b/Lib/packaging/command/bdist.py --- a/Lib/packaging/command/bdist.py +++ b/Lib/packaging/command/bdist.py @@ -128,6 +128,7 @@ for i in range(len(self.formats)): cmd_name = commands[i] sub_cmd = self.get_reinitialized_command(cmd_name) + sub_cmd.format = self.formats[i] # passing the owner and group names for tar archiving if cmd_name == 'bdist_dumb': -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:52 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_typos_in_class_names?= Message-ID: http://hg.python.org/cpython/rev/d516d03e3e4b changeset: 70586:d516d03e3e4b user: ?ric Araujo date: Wed Jun 01 14:41:11 2011 +0200 summary: Fix typos in class names files: Lib/packaging/pypi/simple.py | 4 ++-- Lib/packaging/pypi/xmlrpc.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -1,6 +1,6 @@ """Spider using the screen-scraping "simple" PyPI API. -This module contains the class SimpleIndexCrawler, a simple spider that +This module contains the class Crawler, a simple spider that can be used to find and retrieve distributions from a project index (like the Python Package Index), using its so-called simple API (see reference implementation available at http://pypi.python.org/simple/). @@ -178,7 +178,7 @@ def get_releases(self, requirements, prefer_final=None, force_update=False): - """Search for releases and return a ReleaseList object containing + """Search for releases and return a ReleasesList object containing the results. """ predicate = get_version_predicate(requirements) diff --git a/Lib/packaging/pypi/xmlrpc.py b/Lib/packaging/pypi/xmlrpc.py --- a/Lib/packaging/pypi/xmlrpc.py +++ b/Lib/packaging/pypi/xmlrpc.py @@ -31,11 +31,11 @@ If no server_url is specified, use the default PyPI XML-RPC URL, defined in the DEFAULT_XMLRPC_INDEX_URL constant:: - >>> client = XMLRPCClient() + >>> client = Client() >>> client.server_url == DEFAULT_XMLRPC_INDEX_URL True - >>> client = XMLRPCClient("http://someurl/") + >>> client = Client("http://someurl/") >>> client.server_url 'http://someurl/' """ @@ -69,7 +69,7 @@ informations (eg. make a new XML-RPC call). :: - >>> client = XMLRPCClient() + >>> client = Client() >>> client.get_releases('Foo') ['1.1', '1.2', '1.3'] @@ -189,7 +189,7 @@ If no server proxy is defined yet, creates a new one:: - >>> client = XmlRpcClient() + >>> client = Client() >>> client.proxy() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:53 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:53 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_The_compiler_class_for_EMX_?= =?utf8?q?was_removed?= Message-ID: http://hg.python.org/cpython/rev/c3f8991cd74d changeset: 70587:c3f8991cd74d user: ?ric Araujo date: Wed Jun 01 15:20:44 2011 +0200 summary: The compiler class for EMX was removed files: Lib/packaging/compiler/__init__.py | 5 +---- Lib/packaging/compiler/ccompiler.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Lib/packaging/compiler/__init__.py b/Lib/packaging/compiler/__init__.py --- a/Lib/packaging/compiler/__init__.py +++ b/Lib/packaging/compiler/__init__.py @@ -83,19 +83,16 @@ # patterns. Order is important; platform mappings are preferred over # OS names. _default_compilers = ( - # Platform string mappings # on a cygwin built python we can use gcc like an ordinary UNIXish # compiler ('cygwin.*', 'unix'), - ('os2emx', 'emx'), # OS name mappings ('posix', 'unix'), ('nt', 'msvc'), - - ) +) def get_default_compiler(osname=None, platform=None): """ Determine the default compiler to use for the given platform. diff --git a/Lib/packaging/compiler/ccompiler.py b/Lib/packaging/compiler/ccompiler.py --- a/Lib/packaging/compiler/ccompiler.py +++ b/Lib/packaging/compiler/ccompiler.py @@ -352,7 +352,7 @@ return macros, objects, extra, pp_opts, build def _get_cc_args(self, pp_opts, debug, before): - # works for unixccompiler, emxccompiler, cygwinccompiler + # works for unixccompiler and cygwinccompiler cc_args = pp_opts + ['-c'] if debug: cc_args[:0] = ['-g'] -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:54 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:54 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_markup=3A_a?= =?utf8?q?rguments_in_a_class_directive_are_=5F=5Finit=5F=5F_arguments=2C_?= =?utf8?q?not_base?= Message-ID: http://hg.python.org/cpython/rev/12c1182f33bc changeset: 70588:12c1182f33bc branch: 3.2 parent: 70581:26e25dc1354e user: ?ric Araujo date: Tue May 31 21:50:38 2011 +0200 summary: Fix markup: arguments in a class directive are __init__ arguments, not base classes files: Doc/distutils/apiref.rst | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1814,7 +1814,7 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file -.. class:: bdist_msi(Command) +.. class:: bdist_msi Builds a `Windows Installer`_ (.msi) binary package. @@ -1893,9 +1893,9 @@ :synopsis: Build the .py/.pyc files of a package -.. class:: build_py(Command) - -.. class:: build_py_2to3(build_py) +.. class:: build_py + +.. class:: build_py_2to3 Alternative implementation of build_py which also runs the 2to3 conversion library on each .py file that is going to be -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:54 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:54 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/5e75517696d4 changeset: 70589:5e75517696d4 branch: 3.2 parent: 70575:22457ac2c2df parent: 70588:12c1182f33bc user: ?ric Araujo date: Wed Jun 01 19:39:27 2011 +0200 summary: Branch merge files: Doc/distutils/apiref.rst | 8 ++++---- Modules/_threadmodule.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1814,7 +1814,7 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file -.. class:: bdist_msi(Command) +.. class:: bdist_msi Builds a `Windows Installer`_ (.msi) binary package. @@ -1893,9 +1893,9 @@ :synopsis: Build the .py/.pyc files of a package -.. class:: build_py(Command) - -.. class:: build_py_2to3(build_py) +.. class:: build_py + +.. class:: build_py_2to3 Alternative implementation of build_py which also runs the 2to3 conversion library on each .py file that is going to be diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1091,7 +1091,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:55 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:55 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_duplicate_entry_for_?= =?utf8?q?Josip?= Message-ID: http://hg.python.org/cpython/rev/5b2d84830d05 changeset: 70590:5b2d84830d05 parent: 70577:e064191a3876 user: ?ric Araujo date: Wed Jun 01 19:41:21 2011 +0200 summary: Remove duplicate entry for Josip files: Misc/ACKS | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -255,7 +255,6 @@ Andy Dustman Gary Duzan Eugene Dvurechenski -Josip Dzolonga Maxim Dzumanenko Walter D?rwald Hans Eckardt -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:55 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:55 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/e1830b97a195 changeset: 70591:e1830b97a195 parent: 70590:5b2d84830d05 parent: 70587:c3f8991cd74d user: ?ric Araujo date: Wed Jun 01 19:47:06 2011 +0200 summary: Branch merge files: Lib/packaging/command/bdist.py | 1 + Lib/packaging/command/sdist.py | 36 +-- Lib/packaging/compiler/__init__.py | 5 +- Lib/packaging/compiler/ccompiler.py | 2 +- Lib/packaging/fancy_getopt.py | 119 ++------- Lib/packaging/pypi/simple.py | 4 +- Lib/packaging/pypi/xmlrpc.py | 8 +- Lib/packaging/tests/test_command_build_ext.py | 4 +- Lib/packaging/tests/test_command_sdist.py | 9 +- 9 files changed, 45 insertions(+), 143 deletions(-) diff --git a/Lib/packaging/command/bdist.py b/Lib/packaging/command/bdist.py --- a/Lib/packaging/command/bdist.py +++ b/Lib/packaging/command/bdist.py @@ -128,6 +128,7 @@ for i in range(len(self.formats)): cmd_name = commands[i] sub_cmd = self.get_reinitialized_command(cmd_name) + sub_cmd.format = self.formats[i] # passing the owner and group names for tar archiving if cmd_name == 'bdist_dumb': diff --git a/Lib/packaging/command/sdist.py b/Lib/packaging/command/sdist.py --- a/Lib/packaging/command/sdist.py +++ b/Lib/packaging/command/sdist.py @@ -1,10 +1,9 @@ """Create a source distribution.""" import os +import re import sys -import re from io import StringIO -from glob import glob from shutil import get_archive_formats, rmtree from packaging import logger @@ -203,45 +202,14 @@ def add_defaults(self): """Add all the default files to self.filelist: - - README or README.txt - - test/test*.py - all pure Python modules mentioned in setup script - all files pointed by package_data (build_py) - all files defined in data_files. - all files defined as scripts. - all C sources listed as part of extensions or C libraries in the setup script (doesn't catch C headers!) - Warns if (README or README.txt) or setup.py are missing; everything - else is optional. + Everything is optional. """ - standards = [('README', 'README.txt')] - for fn in standards: - if isinstance(fn, tuple): - alts = fn - got_it = False - for fn in alts: - if os.path.exists(fn): - got_it = True - self.filelist.append(fn) - break - - if not got_it: - logger.warning( - '%s: standard file not found: should have one of %s', - self.get_command_name(), ', '.join(alts)) - else: - if os.path.exists(fn): - self.filelist.append(fn) - else: - logger.warning('%s: standard file %r not found', - self.get_command_name(), fn) - - optional = ['test/test*.py', 'setup.cfg'] - for pattern in optional: - files = [f for f in glob(pattern) if os.path.isfile(f)] - if files: - self.filelist.extend(files) - for cmd_name in get_command_names(): try: cmd_obj = self.get_finalized_command(cmd_name) diff --git a/Lib/packaging/compiler/__init__.py b/Lib/packaging/compiler/__init__.py --- a/Lib/packaging/compiler/__init__.py +++ b/Lib/packaging/compiler/__init__.py @@ -83,19 +83,16 @@ # patterns. Order is important; platform mappings are preferred over # OS names. _default_compilers = ( - # Platform string mappings # on a cygwin built python we can use gcc like an ordinary UNIXish # compiler ('cygwin.*', 'unix'), - ('os2emx', 'emx'), # OS name mappings ('posix', 'unix'), ('nt', 'msvc'), - - ) +) def get_default_compiler(osname=None, platform=None): """ Determine the default compiler to use for the given platform. diff --git a/Lib/packaging/compiler/ccompiler.py b/Lib/packaging/compiler/ccompiler.py --- a/Lib/packaging/compiler/ccompiler.py +++ b/Lib/packaging/compiler/ccompiler.py @@ -352,7 +352,7 @@ return macros, objects, extra, pp_opts, build def _get_cc_args(self, pp_opts, debug, before): - # works for unixccompiler, emxccompiler, cygwinccompiler + # works for unixccompiler and cygwinccompiler cc_args = pp_opts + ['-c'] if debug: cc_args[:0] = ['-g'] diff --git a/Lib/packaging/fancy_getopt.py b/Lib/packaging/fancy_getopt.py --- a/Lib/packaging/fancy_getopt.py +++ b/Lib/packaging/fancy_getopt.py @@ -13,7 +13,6 @@ import getopt import re import sys -import string import textwrap from packaging.errors import PackagingGetoptError, PackagingArgError @@ -142,20 +141,20 @@ for option in self.option_table: if len(option) == 3: - integer, short, help = option + longopt, short, help = option repeat = 0 elif len(option) == 4: - integer, short, help, repeat = option + longopt, short, help, repeat = option else: # the option table is part of the code, so simply # assert that it is correct raise ValueError("invalid option tuple: %r" % option) # Type- and value-check the option names - if not isinstance(integer, str) or len(integer) < 2: + if not isinstance(longopt, str) or len(longopt) < 2: raise PackagingGetoptError( ("invalid long option '%s': " - "must be a string of length >= 2") % integer) + "must be a string of length >= 2") % longopt) if (not ((short is None) or (isinstance(short, str) and len(short) == 1))): @@ -163,55 +162,55 @@ ("invalid short option '%s': " "must be a single character or None") % short) - self.repeat[integer] = repeat - self.long_opts.append(integer) + self.repeat[longopt] = repeat + self.long_opts.append(longopt) - if integer[-1] == '=': # option takes an argument? + if longopt[-1] == '=': # option takes an argument? if short: short = short + ':' - integer = integer[0:-1] - self.takes_arg[integer] = 1 + longopt = longopt[0:-1] + self.takes_arg[longopt] = 1 else: # Is option is a "negative alias" for some other option (eg. # "quiet" == "!verbose")? - alias_to = self.negative_alias.get(integer) + alias_to = self.negative_alias.get(longopt) if alias_to is not None: if self.takes_arg[alias_to]: raise PackagingGetoptError( ("invalid negative alias '%s': " "aliased option '%s' takes a value") % \ - (integer, alias_to)) + (longopt, alias_to)) - self.long_opts[-1] = integer # XXX redundant?! - self.takes_arg[integer] = 0 + self.long_opts[-1] = longopt # XXX redundant?! + self.takes_arg[longopt] = 0 else: - self.takes_arg[integer] = 0 + self.takes_arg[longopt] = 0 # If this is an alias option, make sure its "takes arg" flag is # the same as the option it's aliased to. - alias_to = self.alias.get(integer) + alias_to = self.alias.get(longopt) if alias_to is not None: - if self.takes_arg[integer] != self.takes_arg[alias_to]: + if self.takes_arg[longopt] != self.takes_arg[alias_to]: raise PackagingGetoptError( ("invalid alias '%s': inconsistent with " "aliased option '%s' (one of them takes a value, " - "the other doesn't") % (integer, alias_to)) + "the other doesn't") % (longopt, alias_to)) # Now enforce some bondage on the long option name, so we can # later translate it to an attribute name on some object. Have # to do this a bit late to make sure we've removed any trailing # '='. - if not longopt_re.match(integer): + if not longopt_re.match(longopt): raise PackagingGetoptError( ("invalid long option name '%s' " + - "(must be letters, numbers, hyphens only") % integer) + "(must be letters, numbers, hyphens only") % longopt) - self.attr_name[integer] = integer.replace('-', '_') + self.attr_name[longopt] = longopt.replace('-', '_') if short: self.short_opts.append(short) - self.short2long[short[0]] = integer + self.short2long[short[0]] = longopt def getopt(self, args=None, object=None): """Parse command-line options in args. Store as attributes on object. @@ -297,10 +296,10 @@ # First pass: determine maximum length of long option names max_opt = 0 for option in self.option_table: - integer = option[0] + longopt = option[0] short = option[1] - l = len(integer) - if integer[-1] == '=': + l = len(longopt) + if longopt[-1] == '=': l = l - 1 if short is not None: l = l + 5 # " (-x)" where short == 'x' @@ -340,20 +339,20 @@ lines = ['Option summary:'] for option in self.option_table: - integer, short, help = option[:3] + longopt, short, help = option[:3] text = textwrap.wrap(help, text_width) # Case 1: no short option at all (makes life easy) if short is None: if text: - lines.append(" --%-*s %s" % (max_opt, integer, text[0])) + lines.append(" --%-*s %s" % (max_opt, longopt, text[0])) else: - lines.append(" --%-*s " % (max_opt, integer)) + lines.append(" --%-*s " % (max_opt, longopt)) # Case 2: we have a short option, so we have to include it # just after the long option else: - opt_names = "%s (-%s)" % (integer, short) + opt_names = "%s (-%s)" % (longopt, short) if text: lines.append(" --%-*s %s" % (max_opt, opt_names, text[0])) @@ -378,68 +377,6 @@ return parser.getopt(args, object) -WS_TRANS = str.maketrans(string.whitespace, ' ' * len(string.whitespace)) - - -def wrap_text(text, width): - """Split *text* into lines of no more than *width* characters each. - - *text* is a str and *width* an int. Returns a list of str. - """ - - if text is None: - return [] - if len(text) <= width: - return [text] - - text = text.expandtabs() - text = text.translate(WS_TRANS) - - chunks = re.split(r'( +|-+)', text) - chunks = [_f for _f in chunks if _f] # ' - ' results in empty strings - lines = [] - - while chunks: - - cur_line = [] # list of chunks (to-be-joined) - cur_len = 0 # length of current line - - while chunks: - l = len(chunks[0]) - if cur_len + l <= width: # can squeeze (at least) this chunk in - cur_line.append(chunks[0]) - del chunks[0] - cur_len = cur_len + l - else: # this line is full - # drop last chunk if all space - if cur_line and cur_line[-1][0] == ' ': - del cur_line[-1] - break - - if chunks: # any chunks left to process? - - # if the current line is still empty, then we had a single - # chunk that's too big too fit on a line -- so we break - # down and break it up at the line width - if cur_len == 0: - cur_line.append(chunks[0][0:width]) - chunks[0] = chunks[0][width:] - - # all-whitespace chunks at the end of a line can be discarded - # (and we know from the re.split above that if a chunk has - # *any* whitespace, it is *all* whitespace) - if chunks[0][0] == ' ': - del chunks[0] - - # and store this line in the list-of-all-lines -- as a single - # string, of course! - lines.append(''.join(cur_line)) - - # while chunks - - return lines - - class OptionDummy: """Dummy class just used as a place to hold command-line option values as instance attributes.""" diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -1,6 +1,6 @@ """Spider using the screen-scraping "simple" PyPI API. -This module contains the class SimpleIndexCrawler, a simple spider that +This module contains the class Crawler, a simple spider that can be used to find and retrieve distributions from a project index (like the Python Package Index), using its so-called simple API (see reference implementation available at http://pypi.python.org/simple/). @@ -178,7 +178,7 @@ def get_releases(self, requirements, prefer_final=None, force_update=False): - """Search for releases and return a ReleaseList object containing + """Search for releases and return a ReleasesList object containing the results. """ predicate = get_version_predicate(requirements) diff --git a/Lib/packaging/pypi/xmlrpc.py b/Lib/packaging/pypi/xmlrpc.py --- a/Lib/packaging/pypi/xmlrpc.py +++ b/Lib/packaging/pypi/xmlrpc.py @@ -31,11 +31,11 @@ If no server_url is specified, use the default PyPI XML-RPC URL, defined in the DEFAULT_XMLRPC_INDEX_URL constant:: - >>> client = XMLRPCClient() + >>> client = Client() >>> client.server_url == DEFAULT_XMLRPC_INDEX_URL True - >>> client = XMLRPCClient("http://someurl/") + >>> client = Client("http://someurl/") >>> client.server_url 'http://someurl/' """ @@ -69,7 +69,7 @@ informations (eg. make a new XML-RPC call). :: - >>> client = XMLRPCClient() + >>> client = Client() >>> client.get_releases('Foo') ['1.1', '1.2', '1.3'] @@ -189,7 +189,7 @@ If no server proxy is defined yet, creates a new one:: - >>> client = XmlRpcClient() + >>> client = Client() >>> client.proxy() diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -370,8 +370,8 @@ src = _get_source_filename() if not os.path.exists(src): if verbose: - print ('test_build_ext: Cannot find source code (test' - ' must run in python build dir)') + print('test_command_build_ext: Cannot find source code (test' + ' must run in python build dir)') return unittest.TestSuite() else: return unittest.makeSuite(BuildExtTestCase) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -33,7 +33,6 @@ MANIFEST = """\ # file GENERATED by packaging, do NOT edit -README inroot.txt data%(sep)sdata.dt scripts%(sep)sscript.py @@ -129,7 +128,7 @@ content = zip_file.namelist() # making sure everything has been pruned correctly - self.assertEqual(len(content), 3) + self.assertEqual(len(content), 2) @requires_zlib @unittest.skipIf(find_executable('tar') is None or @@ -214,7 +213,7 @@ # Making sure everything was added. This includes 9 code and data # files in addition to PKG-INFO. - self.assertEqual(len(content), 10) + self.assertEqual(len(content), 9) # Checking the MANIFEST with open(join(self.tmp_dir, 'MANIFEST')) as fp: @@ -331,7 +330,7 @@ with open(cmd.manifest) as f: manifest = [line.strip() for line in f.read().split('\n') if line.strip() != ''] - self.assertEqual(len(manifest), 4) + self.assertEqual(len(manifest), 3) # Adding a file self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') @@ -348,7 +347,7 @@ if line.strip() != ''] # Do we have the new file in MANIFEST? - self.assertEqual(len(manifest2), 5) + self.assertEqual(len(manifest2), 4) self.assertIn('doc2.txt', manifest2[-1]) @requires_zlib -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 19:47:56 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 19:47:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/9552a0b36f60 changeset: 70592:9552a0b36f60 parent: 70591:e1830b97a195 parent: 70589:5e75517696d4 user: ?ric Araujo date: Wed Jun 01 19:47:24 2011 +0200 summary: Merge 3.2 files: Doc/distutils/apiref.rst | 8 ++++---- Modules/_threadmodule.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -1814,7 +1814,7 @@ .. module:: distutils.command.bdist_msi :synopsis: Build a binary distribution as a Windows MSI file -.. class:: bdist_msi(Command) +.. class:: bdist_msi Builds a `Windows Installer`_ (.msi) binary package. @@ -1893,9 +1893,9 @@ :synopsis: Build the .py/.pyc files of a package -.. class:: build_py(Command) - -.. class:: build_py_2to3(build_py) +.. class:: build_py + +.. class:: build_py_2to3 Alternative implementation of build_py which also runs the 2to3 conversion library on each .py file that is going to be diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1098,7 +1098,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 20:24:40 2011 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Jun 2011 20:24:40 +0200 (CEST) Subject: [Python-checkins] r88848 - tracker/instances/python-dev/html/style.css Message-ID: <3Ql0TN6MQkz7LlG@mail.python.org> Author: ezio.melotti Date: Wed Jun 1 20:24:40 2011 New Revision: 88848 Log: Remove the nowrap from the table cells so that long nosy lists do not overflow the page. Modified: tracker/instances/python-dev/html/style.css Modified: tracker/instances/python-dev/html/style.css ============================================================================== --- tracker/instances/python-dev/html/style.css (original) +++ tracker/instances/python-dev/html/style.css Wed Jun 1 20:24:40 2011 @@ -185,7 +185,6 @@ color: #333; empty-cells: show; padding: 5px; - white-space: nowrap; } table.form td.optional { From python-checkins at python.org Wed Jun 1 20:31:19 2011 From: python-checkins at python.org (charles-francois.natali) Date: Wed, 01 Jun 2011 20:31:19 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312196=3A_Add_a_not?= =?utf8?q?e_on_os=2Epipe2=28=29_in_the_=22Whats=27_new_in_Python_3=2E3=22?= Message-ID: http://hg.python.org/cpython/rev/4124d1f75b93 changeset: 70593:4124d1f75b93 user: Charles-Fran?ois Natali date: Wed Jun 01 20:30:52 2011 +0200 summary: Issue #12196: Add a note on os.pipe2() in the "Whats' new in Python 3.3" document. files: Doc/whatsnew/3.3.rst | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -106,6 +106,11 @@ os -- +* The :mod:`os` module has a new :func:`~os.pipe2` function that makes it + possible to create a pipe with :data:`~os.O_CLOEXEC` or + :data:`~os.O_NONBLOCK` flags set atomically. This is especially useful to + avoid race conditions in multi-threaded programs. + * The :mod:`os` module has a new :func:`~os.sendfile` function which provides an efficent "zero-copy" way for copying data from one file (or socket) descriptor to another. The phrase "zero-copy" refers to the fact that all of -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 20:45:03 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 20:45:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Add_documentation_for_the_p?= =?utf8?q?ackaging_module=2E?= Message-ID: http://hg.python.org/cpython/rev/1f7297534424 changeset: 70594:1f7297534424 user: ?ric Araujo date: Wed Jun 01 20:42:49 2011 +0200 summary: Add documentation for the packaging module. This updates the user guide to refer to Packaging instead of Distutils. Some files still require an update. files: Doc/contents.rst | 2 +- Doc/distutils/index.rst | 13 + Doc/install/index.rst | Bin Doc/install/install.rst | 1029 ++++++++++ Doc/install/pysetup-config.rst | 44 + Doc/install/pysetup-servers.rst | 61 + Doc/install/pysetup.rst | 163 + Doc/library/depgraph-output.png | Bin Doc/library/distutils.rst | 5 + Doc/library/packaging-misc.rst | 27 + Doc/library/packaging.command.rst | 111 + Doc/library/packaging.compiler.rst | 672 ++++++ Doc/library/packaging.database.rst | 324 +++ Doc/library/packaging.depgraph.rst | 199 + Doc/library/packaging.dist.rst | 102 + Doc/library/packaging.fancy_getopt.rst | 75 + Doc/library/packaging.install.rst | 112 + Doc/library/packaging.metadata.rst | 122 + Doc/library/packaging.pypi.dist.rst | 114 + Doc/library/packaging.pypi.rst | 53 + Doc/library/packaging.pypi.simple.rst | 157 + Doc/library/packaging.pypi.xmlrpc.rst | 143 + Doc/library/packaging.rst | 78 + Doc/library/packaging.tests.pypi_server.rst | 105 + Doc/library/packaging.util.rst | 186 + Doc/library/packaging.version.rst | 104 + Doc/library/python.rst | 1 + Doc/packaging/builtdist.rst | 307 ++ Doc/packaging/commandhooks.rst | 31 + Doc/packaging/commandref.rst | 349 +++ Doc/packaging/configfile.rst | 125 + Doc/packaging/examples.rst | 334 +++ Doc/packaging/extending.rst | 95 + Doc/packaging/index.rst | 45 + Doc/packaging/introduction.rst | 193 + Doc/packaging/packageindex.rst | 104 + Doc/packaging/setupcfg.rst | 648 ++++++ Doc/packaging/setupscript.rst | 689 ++++++ Doc/packaging/sourcedist.rst | 273 ++ Doc/packaging/tutorial.rst | 112 + Doc/packaging/uploading.rst | 80 + Doc/tools/sphinxext/indexcontent.html | 4 +- 42 files changed, 7388 insertions(+), 3 deletions(-) diff --git a/Doc/contents.rst b/Doc/contents.rst --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -11,7 +11,7 @@ library/index.rst extending/index.rst c-api/index.rst - distutils/index.rst + packaging/index.rst install/index.rst documenting/index.rst howto/index.rst diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -29,3 +29,16 @@ extending.rst commandref.rst apiref.rst + +Another document describes how to install modules and extensions packaged +following the above guidelines: + +.. toctree:: + + install.rst + + +.. seealso:: + + :ref:`packaging-index` and :ref:`packaging-install-index` + Documentation of Packaging, the new version of Distutils. diff --git a/Doc/install/index.rst b/Doc/distutils/install.rst rename from Doc/install/index.rst rename to Doc/distutils/install.rst diff --git a/Doc/install/install.rst b/Doc/install/install.rst new file mode 100644 --- /dev/null +++ b/Doc/install/install.rst @@ -0,0 +1,1029 @@ +.. highlightlang:: none + +==================================== +Installing Python projects: overwiew +==================================== + +.. _packaging_packaging-intro: + +Introduction +============ + +Although Python's extensive standard library covers many programming needs, +there often comes a time when you need to add new functionality to your Python +installation in the form of third-party modules. This might be necessary to +support your own programming, or to support an application that you want to use +and that happens to be written in Python. + +In the past, there was little support for adding third-party modules to an +existing Python installation. With the introduction of the Python Distribution +Utilities (Distutils for short) in Python 2.0, this changed. However, not all +problems were solved; end-users had to rely on ``easy_install`` or +``pip`` to download third-party modules from PyPI, uninstall distributions or do +other maintenance operations. Packaging is a more complete replacement for +Distutils, in the standard library, with a backport named Distutils2 available +for older Python versions. + +This document is aimed primarily at people who need to install third-party +Python modules: end-users and system administrators who just need to get some +Python application running, and existing Python programmers who want to add +new goodies to their toolbox. You don't need to know Python to read this +document; there will be some brief forays into using Python's interactive mode +to explore your installation, but that's it. If you're looking for information +on how to distribute your own Python modules so that others may use them, see +the :ref:`packaging-index` manual. + + +.. _packaging-trivial-install: + +Best case: trivial installation +------------------------------- + +In the best case, someone will have prepared a special version of the module +distribution you want to install that is targeted specifically at your platform +and can be installed just like any other software on your platform. For example, +the module's developer might make an executable installer available for Windows +users, an RPM package for users of RPM-based Linux systems (Red Hat, SuSE, +Mandrake, and many others), a Debian package for users of Debian and derivative +systems, and so forth. + +In that case, you would use the standard system tools to download and install +the specific installer for your platform and its dependencies. + +Of course, things will not always be that easy. You might be interested in a +module whose distribution doesn't have an easy-to-use installer for your +platform. In that case, you'll have to start with the source distribution +released by the module's author/maintainer. Installing from a source +distribution is not too hard, as long as the modules are packaged in the +standard way. The bulk of this document addresses the building and installing +of modules from standard source distributions. + + +.. _packaging-distutils: + +The Python standard: Distutils +------------------------------ + +If you download a source distribution of a module, it will be obvious whether +it was packaged and distributed using Distutils. First, the distribution's name +and version number will be featured prominently in the name of the downloaded +archive, e.g. :file:`foo-1.0.tar.gz` or :file:`widget-0.9.7.zip`. Next, the +archive will unpack into a similarly-named directory: :file:`foo-1.0` or +:file:`widget-0.9.7`. Additionally, the distribution may contain a +:file:`setup.cfg` file and a file named :file:`README.txt` ---or possibly just +:file:`README`--- explaining that building and installing the module +distribution is a simple matter of issuing the following command at your shell's +prompt:: + + python setup.py install + +Third-party projects have extended Distutils to work around its limitations or +add functionality. After some years of near-inactivity in Distutils, a new +maintainer has started to standardize good ideas in PEPs and implement them in a +new, improved version of Distutils, called Distutils2 or Packaging. + + +.. _packaging-new-standard: + +The new standard: Packaging +--------------------------- + +The rules described in the first paragraph above apply to Packaging-based +projects too: a source distribution will have a name like +:file:`widget-0.9.7.zip`. One of the main differences with Distutils is that +distributions no longer have a :file:`setup.py` script; it used to cause a +number of issues. Now there is a unique script installed with Python itself:: + + pysetup install widget-0.9.7.zip + +Running this command is enough to build and install projects (Python modules or +packages, scripts or whole applications), without even having to unpack the +archive. It is also compatible with Distutils-based distributions. + +Unless you have to perform non-standard installations or customize the build +process, you can stop reading this manual ---the above command is everything you +need to get out of it. + +With :program:`pysetup`, you won't even have to manually download a distribution +before installing it; see :ref:`packaging-pysetup`. + + +.. _packaging-standard-install: + +Standard build and install +========================== + +As described in section :ref:`packaging-new-standard`, building and installing +a module distribution using Packaging usually comes down to one simple +command:: + + pysetup run install_dist + +How you actually run this command depends on the platform and the command line +interface it provides: + +* **Unix**: Use a shell prompt. +* **Windows**: Open a command prompt ("DOS console") or use :command:`Powershell`. +* **OS X**: Open a :command:`Terminal`. + + +.. _packaging-platform-variations: + +Platform variations +------------------- + +The setup command is meant to be run from the root directory of the source +distribution, i.e. the top-level subdirectory that the module source +distribution unpacks into. For example, if you've just downloaded a module +source distribution :file:`foo-1.0.tar.gz` onto a Unix system, the normal +steps to follow are these:: + + gunzip -c foo-1.0.tar.gz | tar xf - # unpacks into directory foo-1.0 + cd foo-1.0 + pysetup run install_dist + +On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the +archive file to :file:`C:\\Temp`, then it would unpack into +:file:`C:\\Temp\\foo-1.0`. To actually unpack the archive, you can use either +an archive manipulator with a graphical user interface (such as WinZip or 7-Zip) +or a command-line tool (such as :program:`unzip`, :program:`pkunzip` or, again, +:program:`7z`). Then, open a command prompt window ("DOS box" or +Powershell), and run:: + + cd c:\Temp\foo-1.0 + pysetup run install_dist + + +.. _packaging-splitting-up: + +Splitting the job up +-------------------- + +Running ``pysetup run install_dist`` builds and installs all modules in one go. If you +prefer to work incrementally ---especially useful if you want to customize the +build process, or if things are going wrong--- you can use the setup script to +do one thing at a time. This is a valuable tool when different users will perform +separately the build and install steps. For example, you might want to build a +module distribution and hand it off to a system administrator for installation +(or do it yourself, but with super-user or admin privileges). + +For example, to build everything in one step and then install everything +in a second step, you aptly invoke two distinct Packaging commands:: + + pysetup run build + pysetup run install_dist + +If you do this, you will notice that invoking the :command:`install_dist` command +first runs the :command:`build` command, which ---in this case--- quickly +notices it can spare itself the work, since everything in the :file:`build` +directory is up-to-date. + +You may often ignore this ability to divide the process in steps if all you do +is installing modules downloaded from the Internet, but it's very handy for +more advanced tasks. If you find yourself in the need for distributing your own +Python modules and extensions, though, you'll most likely run many individual +Packaging commands. + + +.. _packaging-how-build-works: + +How building works +------------------ + +As implied above, the :command:`build` command is responsible for collecting +and placing the files to be installed into a *build directory*. By default, +this is :file:`build`, under the distribution root. If you're excessively +concerned with speed, or want to keep the source tree pristine, you can specify +a different build directory with the :option:`--build-base` option. For example:: + + pysetup run build --build-base /tmp/pybuild/foo-1.0 + +(Or you could do this permanently with a directive in your system or personal +Packaging configuration file; see section :ref:`packaging-config-files`.) +In the usual case, however, all this is unnecessary. + +The build tree's default layout looks like so:: + + --- build/ --- lib/ + or + --- build/ --- lib./ + temp./ + +where ```` expands to a brief description of the current OS/hardware +platform and Python version. The first form, with just a :file:`lib` directory, +is used for pure module distributions (module distributions that +include only pure Python modules). If a module distribution contains any +extensions (modules written in C/C++), then the second form, with two ```` +directories, is used. In that case, the :file:`temp.{plat}` directory holds +temporary files generated during the compile/link process which are not intended +to be installed. In either case, the :file:`lib` (or :file:`lib.{plat}`) directory +contains all Python modules (pure Python and extensions) to be installed. + +In the future, more directories will be added to handle Python scripts, +documentation, binary executables, and whatever else is required to install +Python modules and applications. + + +.. _packaging-how-install-works: + +How installation works +---------------------- + +After the :command:`build` command is run (whether explicitly or by the +:command:`install_dist` command on your behalf), the work of the :command:`install_dist` +command is relatively simple: all it has to do is copy the contents of +:file:`build/lib` (or :file:`build/lib.{plat}`) to the installation directory +of your choice. + +If you don't choose an installation directory ---i.e., if you just run +``pysetup run install_dist``\ --- then the :command:`install_dist` command +installs to the standard location for third-party Python modules. This location +varies by platform and depending on how you built/installed Python itself. On +Unix (and Mac OS X, which is also Unix-based), it also depends on whether the +module distribution being installed is pure Python or contains extensions +("non-pure"): + ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Platform | Standard installation location | Default value | Notes | ++=================+=====================================================+==================================================+=======+ +| Unix (pure) | :file:`{prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Unix (non-pure) | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Windows | :file:`{prefix}\\Lib\\site-packages` | :file:`C:\\Python{XY}\\Lib\\site-packages` | \(2) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ + +Notes: + +(1) + Most Linux distributions include Python as a standard part of the system, so + :file:`{prefix}` and :file:`{exec-prefix}` are usually both :file:`/usr` on + Linux. If you build Python yourself on Linux (or any Unix-like system), the + default :file:`{prefix}` and :file:`{exec-prefix}` are :file:`/usr/local`. + +(2) + The default installation directory on Windows was :file:`C:\\Program + Files\\Python` under Python 1.6a1, 1.5.2, and earlier. + +:file:`{prefix}` and :file:`{exec-prefix}` stand for the directories that Python +is installed to, and where it finds its libraries at run-time. They are always +the same under Windows, and very often the same under Unix and Mac OS X. You +can find out what your Python installation uses for :file:`{prefix}` and +:file:`{exec-prefix}` by running Python in interactive mode and typing a few +simple commands. + +.. TODO link to Doc/using instead of duplicating + +To start the interactive Python interpreter, you need to follow a slightly +different recipe for each platform. Under Unix, just type :command:`python` at +the shell prompt. Under Windows (assuming the Python executable is on your +:envvar:`PATH`, which is the usual case), you can choose :menuselection:`Start --> Run`, +type ``python`` and press ``enter``. Alternatively, you can simply execute +:command:`python` at a command prompt ("DOS console" or Powershell). + +Once the interpreter is started, you type Python code at the prompt. For +example, on my Linux system, I type the three Python statements shown below, +and get the output as shown, to find out my :file:`{prefix}` and :file:`{exec-prefix}`:: + + Python 3.3 (r32:88445, Apr 2 2011, 10:43:54) + Type "help", "copyright", "credits" or "license" for more information. + >>> import sys + >>> sys.prefix + '/usr' + >>> sys.exec_prefix + '/usr' + +If you don't want to install modules to the standard location, or if you don't +have permission to write there, then you need to read about alternate +installations in section :ref:`packaging-alt-install`. If you want to customize your +installation directories more heavily, see section :ref:`packaging-custom-install`. + + +.. _packaging-alt-install: + +Alternate installation +====================== + +Often, it is necessary or desirable to install modules to a location other than +the standard location for third-party Python modules. For example, on a Unix +system you might not have permission to write to the standard third-party module +directory. Or you might wish to try out a module before making it a standard +part of your local Python installation. This is especially true when upgrading +a distribution already present: you want to make sure your existing base of +scripts still works with the new version before actually upgrading. + +The Packaging :command:`install_dist` command is designed to make installing module +distributions to an alternate location simple and painless. The basic idea is +that you supply a base directory for the installation, and the +:command:`install_dist` command picks a set of directories (called an *installation +scheme*) under this base directory in which to install files. The details +differ across platforms, so read whichever of the following sections applies to +you. + + +.. _packaging-alt-install-prefix: + +Alternate installation: the home scheme +--------------------------------------- + +The idea behind the "home scheme" is that you build and maintain a personal +stash of Python modules. This scheme's name is derived from the concept of a +"home" directory on Unix, since it's not unusual for a Unix user to make their +home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. +In spite of its name's origin, this scheme can be used by anyone, regardless +of the operating system. + +Installing a new module distribution in this way is as simple as :: + + pysetup run install_dist --home + +where you can supply any directory you like for the :option:`--home` option. On +Unix, lazy typists can just type a tilde (``~``); the :command:`install_dist` command +will expand this to your home directory:: + + pysetup run install_dist --home ~ + +The :option:`--home` option defines the base directory for the installation. +Under it, files are installed to the following directories: + ++------------------------------+---------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+===========================+=============================+ +| pure module distribution | :file:`{home}/lib/python` | :option:`--install-purelib` | ++------------------------------+---------------------------+-----------------------------+ +| non-pure module distribution | :file:`{home}/lib/python` | :option:`--install-platlib` | ++------------------------------+---------------------------+-----------------------------+ +| scripts | :file:`{home}/bin` | :option:`--install-scripts` | ++------------------------------+---------------------------+-----------------------------+ +| data | :file:`{home}/share` | :option:`--install-data` | ++------------------------------+---------------------------+-----------------------------+ + + +.. _packaging-alt-install-home: + +Alternate installation: Unix (the prefix scheme) +------------------------------------------------ + +The "prefix scheme" is useful when you wish to use one Python installation to +run the build command, but install modules into the third-party module directory +of a different Python installation (or something that looks like a different +Python installation). If this sounds a trifle unusual, it is ---that's why the +"home scheme" comes first. However, there are at least two known cases where the +prefix scheme will be useful. + +First, consider that many Linux distributions put Python in :file:`/usr`, rather +than the more traditional :file:`/usr/local`. This is entirely appropriate, +since in those cases Python is part of "the system" rather than a local add-on. +However, if you are installing Python modules from source, you probably want +them to go in :file:`/usr/local/lib/python2.{X}` rather than +:file:`/usr/lib/python2.{X}`. This can be done with :: + + pysetup run install_dist --prefix /usr/local + +Another possibility is a network filesystem where the name used to write to a +remote directory is different from the name used to read it: for example, the +Python interpreter accessed as :file:`/usr/local/bin/python` might search for +modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to +be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. This could +be done with :: + + pysetup run install_dist --prefix=/mnt/@server/export + +In either case, the :option:`--prefix` option defines the installation base, and +the :option:`--exec-prefix` option defines the platform-specific installation +base, which is used for platform-specific files. (Currently, this just means +non-pure module distributions, but could be expanded to C libraries, binary +executables, etc.) If :option:`--exec-prefix` is not supplied, it defaults to +:option:`--prefix`. Files are installed as follows: + ++------------------------------+-----------------------------------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+=====================================================+=============================+ +| pure module distribution | :file:`{prefix}/lib/python{X.Y}/site-packages` | :option:`--install-purelib` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| non-pure module distribution | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :option:`--install-platlib` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| scripts | :file:`{prefix}/bin` | :option:`--install-scripts` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| data | :file:`{prefix}/share` | :option:`--install-data` | ++------------------------------+-----------------------------------------------------+-----------------------------+ + +There is no requirement that :option:`--prefix` or :option:`--exec-prefix` +actually point to an alternate Python installation; if the directories listed +above do not already exist, they are created at installation time. + +Incidentally, the real reason the prefix scheme is important is simply that a +standard Unix installation uses the prefix scheme, but with :option:`--prefix` +and :option:`--exec-prefix` supplied by Python itself as ``sys.prefix`` and +``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme, +but every time you run ``pysetup run install_dist`` without any other +options, you're using it. + +Note that installing extensions to an alternate Python installation doesn't have +anything to do with how those extensions are built: in particular, extensions +will be compiled using the Python header files (:file:`Python.h` and friends) +installed with the Python interpreter used to run the build command. It is +therefore your responsibility to ensure compatibility between the interpreter +intended to run extensions installed in this way and the interpreter used to +build these same extensions. To avoid problems, it is best to make sure that +the two interpreters are the same version of Python (possibly different builds, +or possibly copies of the same build). (Of course, if your :option:`--prefix` +and :option:`--exec-prefix` don't even point to an alternate Python installation, +this is immaterial.) + + +.. _packaging-alt-install-windows: + +Alternate installation: Windows (the prefix scheme) +--------------------------------------------------- + +Windows has a different and vaguer notion of home directories than Unix, and +since its standard Python installation is simpler, the :option:`--prefix` option +has traditionally been used to install additional packages to arbitrary +locations. :: + + pysetup run install_dist --prefix "\Temp\Python" + +to install modules to the :file:`\\Temp\\Python` directory on the current drive. + +The installation base is defined by the :option:`--prefix` option; the +:option:`--exec-prefix` option is unsupported under Windows. Files are +installed as follows: + ++------------------------------+---------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+===========================+=============================+ +| pure module distribution | :file:`{prefix}` | :option:`--install-purelib` | ++------------------------------+---------------------------+-----------------------------+ +| non-pure module distribution | :file:`{prefix}` | :option:`--install-platlib` | ++------------------------------+---------------------------+-----------------------------+ +| scripts | :file:`{prefix}\\Scripts` | :option:`--install-scripts` | ++------------------------------+---------------------------+-----------------------------+ +| data | :file:`{prefix}\\Data` | :option:`--install-data` | ++------------------------------+---------------------------+-----------------------------+ + + +.. _packaging-custom-install: + +Custom installation +=================== + +Sometimes, the alternate installation schemes described in section +:ref:`packaging-alt-install` just don't do what you want. You might want to tweak +just one or two directories while keeping everything under the same base +directory, or you might want to completely redefine the installation scheme. +In either case, you're creating a *custom installation scheme*. + +You probably noticed the column of "override options" in the tables describing +the alternate installation schemes above. Those options are how you define a +custom installation scheme. These override options can be relative, absolute, +or explicitly defined in terms of one of the installation base directories. +(There are two installation base directories, and they are normally the same +---they only differ when you use the Unix "prefix scheme" and supply different +:option:`--prefix` and :option:`--exec-prefix` options.) + +For example, say you're installing a module distribution to your home directory +under Unix, but you want scripts to go in :file:`~/scripts` rather than +:file:`~/bin`. As you might expect, you can override this directory with the +:option:`--install-scripts` option and, in this case, it makes most sense to supply +a relative path, which will be interpreted relative to the installation base +directory (in our example, your home directory):: + + pysetup run install_dist --home ~ --install-scripts scripts + +Another Unix example: suppose your Python installation was built and installed +with a prefix of :file:`/usr/local/python`. Thus, in a standard installation, +scripts will wind up in :file:`/usr/local/python/bin`. If you want them in +:file:`/usr/local/bin` instead, you would supply this absolute directory for +the :option:`--install-scripts` option:: + + pysetup run install_dist --install-scripts /usr/local/bin + +This command performs an installation using the "prefix scheme", where the +prefix is whatever your Python interpreter was installed with ---in this case, +:file:`/usr/local/python`. + +If you maintain Python on Windows, you might want third-party modules to live in +a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}` +itself. This is almost as easy as customizing the script installation directory +---you just have to remember that there are two types of modules to worry about, +pure modules and non-pure modules (i.e., modules from a non-pure distribution). +For example:: + + pysetup run install_dist --install-purelib Site --install-platlib Site + +.. XXX Nothing is installed right under prefix in windows, is it?? + +The specified installation directories are relative to :file:`{prefix}`. Of +course, you also have to ensure that these directories are in Python's module +search path, such as by putting a :file:`.pth` file in :file:`{prefix}`. See +section :ref:`packaging-search-path` to find out how to modify Python's search path. + +If you want to define an entire installation scheme, you just have to supply all +of the installation directory options. Using relative paths is recommended here. +For example, if you want to maintain all Python module-related files under +:file:`python` in your home directory, and you want a separate directory for +each platform that you use your home directory from, you might define the +following installation scheme:: + + pysetup run install_dist --home ~ \ + --install-purelib python/lib \ + --install-platlib python/'lib.$PLAT' \ + --install-scripts python/scripts \ + --install-data python/data + +or, equivalently, :: + + pysetup run install_dist --home ~/python \ + --install-purelib lib \ + --install-platlib 'lib.$PLAT' \ + --install-scripts scripts \ + --install-data data + +``$PLAT`` doesn't need to be defined as an environment variable ---it will also +be expanded by Packaging as it parses your command line options, just as it +does when parsing your configuration file(s). (More on that later.) + +Obviously, specifying the entire installation scheme every time you install a +new module distribution would be very tedious. To spare you all that work, you +can store it in a Packaging configuration file instead (see section +:ref:`packaging-config-files`), like so:: + + [install_dist] + install-base = $HOME + install-purelib = python/lib + install-platlib = python/lib.$PLAT + install-scripts = python/scripts + install-data = python/data + +or, equivalently, :: + + [install_dist] + install-base = $HOME/python + install-purelib = lib + install-platlib = lib.$PLAT + install-scripts = scripts + install-data = data + +Note that these two are *not* equivalent if you override their installation +base directory when running the setup script. For example, :: + + pysetup run install_dist --install-base /tmp + +would install pure modules to :file:`/tmp/python/lib` in the first case, and +to :file:`/tmp/lib` in the second case. (For the second case, you'd probably +want to supply an installation base of :file:`/tmp/python`.) + +You may have noticed the use of ``$HOME`` and ``$PLAT`` in the sample +configuration file. These are Packaging configuration variables, which +bear a strong resemblance to environment variables. In fact, you can use +environment variables in configuration files on platforms that have such a notion, but +Packaging additionally defines a few extra variables that may not be in your +environment, such as ``$PLAT``. Of course, on systems that don't have +environment variables, such as Mac OS 9, the configuration variables supplied by +the Packaging are the only ones you can use. See section :ref:`packaging-config-files` +for details. + +.. XXX which vars win out eventually in case of clash env or Packaging? + +.. XXX need some Windows examples---when would custom installation schemes be + needed on those platforms? + + +.. XXX Move this section to Doc/using + +.. _packaging-search-path: + +Modifying Python's search path +------------------------------ + +When the Python interpreter executes an :keyword:`import` statement, it searches +for both Python code and extension modules along a search path. A default value +for this path is configured into the Python binary when the interpreter is built. +You can obtain the search path by importing the :mod:`sys` module and printing +the value of ``sys.path``. :: + + $ python + Python 2.2 (#11, Oct 3 2002, 13:31:27) + [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + >>> import sys + >>> sys.path + ['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', + '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', + '/usr/local/lib/python2.3/site-packages'] + >>> + +The null string in ``sys.path`` represents the current working directory. + +The expected convention for locally installed packages is to put them in the +:file:`{...}/site-packages/` directory, but you may want to choose a different +location for some reason. For example, if your site kept by convention all web +server-related software under :file:`/www`. Add-on Python modules might then +belong in :file:`/www/python`, and in order to import them, this directory would +have to be added to ``sys.path``. There are several ways to solve this problem. + +The most convenient way is to add a path configuration file to a directory +that's already on Python's path, usually to the :file:`.../site-packages/` +directory. Path configuration files have an extension of :file:`.pth`, and each +line must contain a single path that will be appended to ``sys.path``. (Because +the new paths are appended to ``sys.path``, modules in the added directories +will not override standard modules. This means you can't use this mechanism for +installing fixed versions of standard modules.) + +Paths can be absolute or relative, in which case they're relative to the +directory containing the :file:`.pth` file. See the documentation of +the :mod:`site` module for more information. + +A slightly less convenient way is to edit the :file:`site.py` file in Python's +standard library, and modify ``sys.path``. :file:`site.py` is automatically +imported when the Python interpreter is executed, unless the :option:`-S` switch +is supplied to suppress this behaviour. So you could simply edit +:file:`site.py` and add two lines to it:: + + import sys + sys.path.append('/www/python/') + +However, if you reinstall the same major version of Python (perhaps when +upgrading from 3.3 to 3.3.1, for example) :file:`site.py` will be overwritten by +the stock version. You'd have to remember that it was modified and save a copy +before doing the installation. + +Alternatively, there are two environment variables that can modify ``sys.path``. +:envvar:`PYTHONHOME` sets an alternate value for the prefix of the Python +installation. For example, if :envvar:`PYTHONHOME` is set to ``/www/python``, +the search path will be set to ``['', '/www/python/lib/pythonX.Y/', +'/www/python/lib/pythonX.Y/plat-linux2', ...]``. + +The :envvar:`PYTHONPATH` variable can be set to a list of paths that will be +added to the beginning of ``sys.path``. For example, if :envvar:`PYTHONPATH` is +set to ``/www/python:/opt/py``, the search path will begin with +``['/www/python', '/opt/py']``. (Note that directories must exist in order to +be added to ``sys.path``; the :mod:`site` module removes non-existent paths.) + +Finally, ``sys.path`` is just a regular Python list, so any Python application +can modify it by adding or removing entries. + + +.. _packaging-config-files: + +Configuration files for Packaging +================================= + +As mentioned above, you can use configuration files to store personal or site +preferences for any option supported by any Packaging command. Depending on your +platform, you can use one of two or three possible configuration files. These +files will be read before parsing the command-line, so they take precedence over +default values. In turn, the command-line will override configuration files. +Lastly, if there are multiple configuration files, values from files read +earlier will be overridden by values from files read later. + +.. XXX "one of two or three possible..." seems wrong info. Below always 3 files + are indicated in the tables. + + +.. _packaging-config-filenames: + +Location and names of configuration files +----------------------------------------- + +The name and location of the configuration files vary slightly across +platforms. On Unix and Mac OS X, these are the three configuration files listed +in the order they are processed: + ++--------------+----------------------------------------------------------+-------+ +| Type of file | Location and filename | Notes | ++==============+==========================================================+=======+ +| system | :file:`{prefix}/lib/python{ver}/packaging/packaging.cfg` | \(1) | ++--------------+----------------------------------------------------------+-------+ +| personal | :file:`$HOME/.pydistutils.cfg` | \(2) | ++--------------+----------------------------------------------------------+-------+ +| local | :file:`setup.cfg` | \(3) | ++--------------+----------------------------------------------------------+-------+ + +Similarly, the configuration files on Windows ---also listed in the order they +are processed--- are these: + ++--------------+-------------------------------------------------+-------+ +| Type of file | Location and filename | Notes | ++==============+=================================================+=======+ +| system | :file:`{prefix}\\Lib\\packaging\\packaging.cfg` | \(4) | ++--------------+-------------------------------------------------+-------+ +| personal | :file:`%HOME%\\pydistutils.cfg` | \(5) | ++--------------+-------------------------------------------------+-------+ +| local | :file:`setup.cfg` | \(3) | ++--------------+-------------------------------------------------+-------+ + +On all platforms, the *personal* file can be temporarily disabled by +means of the `--no-user-cfg` option. + +Notes: + +(1) + Strictly speaking, the system-wide configuration file lives in the directory + where Packaging is installed. + +(2) + On Unix, if the :envvar:`HOME` environment variable is not defined, the + user's home directory will be determined with the :func:`getpwuid` function + from the standard :mod:`pwd` module. Packaging uses the + :func:`os.path.expanduser` function to do this. + +(3) + I.e., in the current directory (usually the location of the setup script). + +(4) + (See also note (1).) Python's default installation prefix is + :file:`C:\\Python`, so the system configuration file is normally + :file:`C:\\Python\\Lib\\packaging\\packaging.cfg`. + +(5) + On Windows, if the :envvar:`HOME` environment variable is not defined, + :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will + be tried. Packaging uses the :func:`os.path.expanduser` function to do this. + + +.. _packaging-config-syntax: + +Syntax of configuration files +----------------------------- + +All Packaging configuration files share the same syntax. Options defined in +them are grouped into sections, and each Packaging command gets its own section. +Additionally, there's a ``global`` section for options that affect every command. +Sections consist of one or more lines containing a single option specified as +``option = value``. + +For example, here's a complete configuration file that forces all commands to +run quietly by default:: + + [global] + verbose = 0 + +If this was the system configuration file, it would affect all processing +of any Python module distribution by any user on the current system. If it was +installed as your personal configuration file (on systems that support them), +it would affect only module distributions processed by you. Lastly, if it was +used as the :file:`setup.cfg` for a particular module distribution, it would +affect that distribution only. + +.. XXX "(on systems that support them)" seems wrong info + +If you wanted to, you could override the default "build base" directory and +make the :command:`build\*` commands always forcibly rebuild all files with +the following:: + + [build] + build-base = blib + force = 1 + +which corresponds to the command-line arguments:: + + pysetup run build --build-base blib --force + +except that including the :command:`build` command on the command-line means +that command will be run. Including a particular command in configuration files +has no such implication; it only means that if the command is run, the options +for it in the configuration file will apply. (This is also true if you run +other commands that derive values from it.) + +You can find out the complete list of options for any command using the +:option:`--help` option, e.g.:: + + pysetup run build --help + +and you can find out the complete list of global options by using +:option:`--help` without a command:: + + pysetup run --help + +See also the "Reference" section of the "Distributing Python Modules" manual. + +.. XXX no links to the relevant section exist. + + +.. _packaging-building-ext: + +Building extensions: tips and tricks +==================================== + +Whenever possible, Packaging tries to use the configuration information made +available by the Python interpreter used to run `pysetup`. +For example, the same compiler and linker flags used to compile Python will also +be used for compiling extensions. Usually this will work well, but in +complicated situations this might be inappropriate. This section discusses how +to override the usual Packaging behaviour. + + +.. _packaging-tweak-flags: + +Tweaking compiler/linker flags +------------------------------ + +Compiling a Python extension written in C or C++ will sometimes require +specifying custom flags for the compiler and linker in order to use a particular +library or produce a special kind of object code. This is especially true if the +extension hasn't been tested on your platform, or if you're trying to +cross-compile Python. + +.. TODO update to new setup.cfg + +In the most general case, the extension author might have foreseen that +compiling the extensions would be complicated, and provided a :file:`Setup` file +for you to edit. This will likely only be done if the module distribution +contains many separate extension modules, or if they often require elaborate +sets of compiler flags in order to work. + +A :file:`Setup` file, if present, is parsed in order to get a list of extensions +to build. Each line in a :file:`Setup` describes a single module. Lines have +the following structure:: + + module ... [sourcefile ...] [cpparg ...] [library ...] + + +Let's examine each of the fields in turn. + +* *module* is the name of the extension module to be built, and should be a + valid Python identifier. You can't just change this in order to rename a module + (edits to the source code would also be needed), so this should be left alone. + +* *sourcefile* is anything that's likely to be a source code file, at least + judging by the filename. Filenames ending in :file:`.c` are assumed to be + written in C, filenames ending in :file:`.C`, :file:`.cc`, and :file:`.c++` are + assumed to be C++, and filenames ending in :file:`.m` or :file:`.mm` are assumed + to be in Objective C. + +* *cpparg* is an argument for the C preprocessor, and is anything starting with + :option:`-I`, :option:`-D`, :option:`-U` or :option:`-C`. + +* *library* is anything ending in :file:`.a` or beginning with :option:`-l` or + :option:`-L`. + +If a particular platform requires a special library on your platform, you can +add it by editing the :file:`Setup` file and running ``pysetup run build``. +For example, if the module defined by the line :: + + foo foomodule.c + +must be linked with the math library :file:`libm.a` on your platform, simply add +:option:`-lm` to the line:: + + foo foomodule.c -lm + +Arbitrary switches intended for the compiler or the linker can be supplied with +the :option:`-Xcompiler` *arg* and :option:`-Xlinker` *arg* options:: + + foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm + +The next option after :option:`-Xcompiler` and :option:`-Xlinker` will be +appended to the proper command line, so in the above example the compiler will +be passed the :option:`-o32` option, and the linker will be passed +:option:`-shared`. If a compiler option requires an argument, you'll have to +supply multiple :option:`-Xcompiler` options; for example, to pass ``-x c++`` +the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``. + +Compiler flags can also be supplied through setting the :envvar:`CFLAGS` +environment variable. If set, the contents of :envvar:`CFLAGS` will be added to +the compiler flags specified in the :file:`Setup` file. + + +.. _packaging-non-ms-compilers: + +Using non-Microsoft compilers on Windows +---------------------------------------- + +.. sectionauthor:: Rene Liebscher + + + +Borland/CodeGear C++ +^^^^^^^^^^^^^^^^^^^^ + +This subsection describes the necessary steps to use Packaging with the Borland +C++ compiler version 5.5. First you have to know that Borland's object file +format (OMF) is different from the format used by the Python version you can +download from the Python or ActiveState Web site. (Python is built with +Microsoft Visual C++, which uses COFF as the object file format.) For this +reason, you have to convert Python's library :file:`python25.lib` into the +Borland format. You can do this as follows: + +.. Should we mention that users have to create cfg-files for the compiler? +.. see also http://community.borland.com/article/0,1410,21205,00.html + +:: + + coff2omf python25.lib python25_bcpp.lib + +The :file:`coff2omf` program comes with the Borland compiler. The file +:file:`python25.lib` is in the :file:`Libs` directory of your Python +installation. If your extension uses other libraries (zlib, ...) you have to +convert them too. + +The converted files have to reside in the same directories as the normal +libraries. + +How does Packaging manage to use these libraries with their changed names? If +the extension needs a library (eg. :file:`foo`) Packaging checks first if it +finds a library with suffix :file:`_bcpp` (eg. :file:`foo_bcpp.lib`) and then +uses this library. In the case it doesn't find such a special library it uses +the default name (:file:`foo.lib`.) [#]_ + +To let Packaging compile your extension with Borland, C++ you now have to +type:: + + pysetup run build --compiler bcpp + +If you want to use the Borland C++ compiler as the default, you could specify +this in your personal or system-wide configuration file for Packaging (see +section :ref:`packaging-config-files`.) + + +.. seealso:: + + `C++Builder Compiler `_ + Information about the free C++ compiler from Borland, including links to the + download pages. + + `Creating Python Extensions Using Borland's Free Compiler `_ + Document describing how to use Borland's free command-line C++ compiler to build + Python. + + +GNU C / Cygwin / MinGW +^^^^^^^^^^^^^^^^^^^^^^ + +This section describes the necessary steps to use Packaging with the GNU C/C++ +compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter +that was built with Cygwin, everything should work without any of these +following steps. + +Not all extensions can be built with MinGW or Cygwin, but many can. Extensions +most likely to not work are those that use C++ or depend on Microsoft Visual C +extensions. + +To let Packaging compile your extension with Cygwin, you have to type:: + + pysetup run build --compiler=cygwin + +and for Cygwin in no-cygwin mode [#]_ or for MinGW, type:: + + pysetup run build --compiler=mingw32 + +If you want to use any of these options/compilers as default, you should +consider writing it in your personal or system-wide configuration file for +Packaging (see section :ref:`packaging-config-files`.) + +Older Versions of Python and MinGW +"""""""""""""""""""""""""""""""""" +The following instructions only apply if you're using a version of Python +inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with +:file:`binutils-2.13.90-20030111-1`). + +These compilers require some special libraries. This task is more complex than +for Borland's C++, because there is no program to convert the library. First +you have to create a list of symbols which the Python DLL exports. (You can find +a good program for this task at +http://www.emmestech.com/software/pexports-0.43/download_pexports.html). + +.. I don't understand what the next line means. --amk + (inclusive the references on data structures.) + +:: + + pexports python25.dll > python25.def + +The location of an installed :file:`python25.dll` will depend on the +installation options and the version and language of Windows. In a "just for +me" installation, it will appear in the root of the installation directory. In +a shared installation, it will be located in the system directory. + +Then you can create from these information an import library for gcc. :: + + /cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a + +The resulting library has to be placed in the same directory as +:file:`python25.lib`. (Should be the :file:`libs` directory under your Python +installation directory.) + +If your extension uses other libraries (zlib,...) you might have to convert +them too. The converted files have to reside in the same directories as the +normal libraries do. + + +.. seealso:: + + `Building Python modules on MS Windows platform with MinGW `_ + Information about building the required libraries for the MinGW + environment. + + +.. rubric:: Footnotes + +.. [#] This also means you could replace all existing COFF-libraries with + OMF-libraries of the same name. + +.. [#] Check http://sources.redhat.com/cygwin/ and http://www.mingw.org/ for + more information. + +.. [#] Then you have no POSIX emulation available, but you also don't need + :file:`cygwin1.dll`. diff --git a/Doc/install/pysetup-config.rst b/Doc/install/pysetup-config.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup-config.rst @@ -0,0 +1,44 @@ +.. _packaging-pysetup-config: + +===================== +Pysetup Configuration +===================== + +Pysetup supports two configuration files: :file:`.pypirc` and :file:`packaging.cfg`. + +.. FIXME integrate with configfile instead of duplicating + +Configuring indexes +------------------- + +You can configure additional indexes in :file:`.pypirc` to be used for index-related +operations. By default, all configured index-servers and package-servers will be used +in an additive fashion. To limit operations to specific indexes, use the :option:`--index` +and :option:`--package-server options`:: + + $ pysetup install --index pypi --package-server django some.project + +Adding indexes to :file:`.pypirc`:: + + [packaging] + index-servers = + pypi + other + + package-servers = + django + + [pypi] + repository: + username: + password: + + [other] + repository: + username: + password: + + [django] + repository: + username: + password: diff --git a/Doc/install/pysetup-servers.rst b/Doc/install/pysetup-servers.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup-servers.rst @@ -0,0 +1,61 @@ +.. _packaging-pysetup-servers: + +=============== +Package Servers +=============== + +Pysetup supports installing Python packages from *Package Servers* in addition +to PyPI indexes and mirrors. + +Package Servers are simple directory listings of Python distributions. Directories +can be served via HTTP or a local file system. This is useful when you want to +dump source distributions in a directory and not worry about the full index structure. + +Serving distributions from Apache +--------------------------------- +:: + + $ mkdir -p /var/www/html/python/distributions + $ cp *.tar.gz /var/www/html/python/distributions/ + + + ServerAdmin webmaster at domain.com + DocumentRoot "/var/www/html/python" + ServerName python.example.org + ErrorLog logs/python.example.org-error.log + CustomLog logs/python.example.org-access.log common + Options Indexes FollowSymLinks MultiViews + DirectoryIndex index.html index.htm + + + Options Indexes FollowSymLinks MultiViews + Order allow,deny + Allow from all + + + +Add the Apache based distribution server to :file:`.pypirc`:: + + [packaging] + package-servers = + apache + + [apache] + repository: http://python.example.org/distributions/ + + +Serving distributions from a file system +---------------------------------------- +:: + + $ mkdir -p /data/python/distributions + $ cp *.tar.gz /data/python/distributions/ + +Add the directory to :file:`.pypirc`:: + + [packaging] + package-servers = + local + + [local] + repository: file:///data/python/distributions/ diff --git a/Doc/install/pysetup.rst b/Doc/install/pysetup.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup.rst @@ -0,0 +1,163 @@ +.. _packaging-pysetup: + +================ +Pysetup Tutorial +================ + +Getting started +--------------- + +Pysetup is a simple script that supports the following features: + +- install, remove, list, and verify Python packages; +- search for available packages on PyPI or any *Simple Index*; +- verify installed packages (md5sum, installed files, version). + + +Finding out what's installed +---------------------------- + +Pysetup makes it easy to find out what Python packages are installed:: + + $ pysetup search virtualenv + virtualenv 1.6 at /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info + + $ pysetup search --all + pyverify 0.8.1 at /opt/python3.3/lib/python3.3/site-packages/pyverify-0.8.1.dist-info + virtualenv 1.6 at /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info + wsgiref 0.1.2 at /opt/python3.3/lib/python3.3/wsgiref.egg-info + ... + + +Installing a distribution +------------------------- + +Pysetup can install a Python project from the following sources: + +- PyPI and Simple Indexes; +- source directories containing a valid :file:`setup.py` or :file:`setup.cfg`; +- distribution source archives (:file:`project-1.0.tar.gz`, :file:`project-1.0.zip`); +- HTTP (http://host/packages/project-1.0.tar.gz). + + +Installing from PyPI and Simple Indexes:: + + $ pysetup install project + $ pysetup install project==1.0 + +Installing from a distribution source archive:: + + $ pysetup install project-1.0.tar.gz + +Installing from a source directory containing a valid :file:`setup.py` or +:file:`setup.cfg`:: + + $ cd path/to/source/directory + $ pysetup install + + $ pysetup install path/to/source/directory + +Installing from HTTP:: + + $ pysetup install http://host/packages/project-1.0.tar.gz + + +Retrieving metadata +------------------- + +You can gather metadata from two sources, a project's source directory or an +installed distribution. The `pysetup metadata` command can retrieve one or +more metadata fields using the `-f` option and a metadata field as the +argument. :: + + $ pysetup metadata virtualenv -f version -f name + Version: + 1.6 + Name: + virtualenv + + $ pysetup metadata virtualenv --all + Metadata-Version: + 1.0 + Name: + virtualenv + Version: + 1.6 + Platform: + UNKNOWN + Summary: + Virtual Python Environment builder + ... + +.. seealso:: + + There are three metadata versions, 1.0, 1.1, and 1.2. The following PEPs + describe specifics of the field names, and their semantics and usage. 1.0 + :PEP:`241`, 1.1 :PEP:`314`, and 1.2 :PEP:`345` + + +Removing a distribution +----------------------- + +You can remove one or more installed distributions using the `pysetup remove` +command:: + + $ pysetup remove virtualenv + removing 'virtualenv': + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/dependency_links.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/entry_points.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/not-zip-safe + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/PKG-INFO + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/SOURCES.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/top_level.txt + Proceed (y/n)? y + success: removed 6 files and 1 dirs + +The optional '-y' argument auto confirms, skipping the conformation prompt:: + + $ pysetup remove virtualenv -y + + +Getting help +------------ + +All pysetup actions take the `-h` and `--help` options which prints the commands +help string to stdout. :: + + $ pysetup remove -h + Usage: pysetup remove dist [-y] + or: pysetup remove --help + + Uninstall a Python package. + + positional arguments: + dist installed distribution name + + optional arguments: + -y auto confirm package removal + +Getting a list of all pysetup actions and global options:: + + $ pysetup --help + Usage: pysetup [options] action [action_options] + + Actions: + run: Run one or several commands + metadata: Display the metadata of a project + install: Install a project + remove: Remove a project + search: Search for a project + graph: Display a graph + create: Create a Project + + To get more help on an action, use: + + pysetup action --help + + Global options: + --verbose (-v) run verbosely (default) + --quiet (-q) run quietly (turns verbosity off) + --dry-run (-n) don't actually do anything + --help (-h) show detailed help message + --no-user-cfg ignore pydistutils.cfg in your home directory + --version Display the version diff --git a/Doc/library/depgraph-output.png b/Doc/library/depgraph-output.png new file mode 100644 index 0000000000000000000000000000000000000000..960bb1b5639e7ff615ddbd6cbf8a542be31d5fe7 GIT binary patch literal 24719 zc%00D3x*H at FQBqn;>Fx%f zvCg^v&-J;VcyqtH&%wiiz4ux(#u&fvZ_c?4Qk0j(!=c1Mp-_0zQsT-e6j~DeVaLLR z-&~f}{RZDK4WCMiqy8fQrZ(n8p-?wa(&CR*T@%+P-LzHrFCJ};;GW)HV<`K|kcx%F za>LfzBD>aDIw9D7-Soc4&y0!mXp=+d^#wI&_EX(*9+!0PYHg+VZ3xv$fRUa7-6(|1^pbKZhJFaw zu$TRS0sP35=y=^Igd#L=6zy)OK(c6>$df0R+1S~Yo%*F=3f`WpptLx{sHVk=r`Bs)E zhb1K?K1oSQeMOCpjd$NDv5<(q`IMjkRyj}n$&)7;k{TKmGBPrXs;a)}=?o-fWa*ii zm&7j-6BE0-xutpky}-i76_=92VqjpH+1%{SxQXc#g>RHZL^%6B?jFD662ZXWU_?xe z|Jj+RRF?A5 at i9FM3lY?#zrB3T#7e=fmq^_l16i1BVZKMJG$H3qytLj(@RPSP7gOF9UQpvX&(kA+_!6m zenmt?wBieLaNt%|RT&11TUu69#>K_)zdGZGw!AnydXXsTg1 at k^a9!AwU*bJ&Xn%$z z>me|h z5)RPjv+2L*bgzzPufQli{Cl=5B_%b(cv?TVu)x5 at ML6wsNVBuELqJUYmR!%1P~p)z z&-d@&+wtF5Vn92bO5R?%_WRHKM-nnJIGERHLms?b&|mqPm#%xXxmKZhJ2EP&)P3L5 zdb)|m*4EbbbiI1J^(yD*fdS>Utx=4bHug?|ud{6dT-Kv^LuiF4q1{r_(k(&6%v%Fb zIbXC|yjErFh~+Zcf;;@)neUFhYk)rW>eS}w=t#dKm~{Q1meJG`vc<~md9m&jPtS+H zfB)9EvwL4r!9&e&k18!KH4GTO<>v1GJHNO|R9Balh=`~}zXjdb*H?eK$;&XHa{~h= zW;{qOzXMW)kbuCa+^pBIH(6-3-0T`e2ZOWuwaet>eukKivI( zuf}OLW;CsoZ^lX>r1GuRNRdHj2*uI);q>-uYq$s57Kxc`%2Nl+=&Q zs8hc`{fS{fyXI?{uxt8X!f37wI&;u^tZ^kibR&Y{Clk!H?Uv!p3fiQV`EJ8p_q+F>9)h+>=Z#-MImzxg$lX0X8%AeKJfOrC zgl5Yn`2YTGxHjFaw}*|9WDqb-VOTSglkzHfzWd{!-yQFCR*HU2q9K=`sh)n-1|eX7 zu%>Zzdist=KIhl03#Pa)gpE;qAfbAbXDwW}9=R?a10y4s=aGGZda3A|BFcWiq6adN zkc#Tv(~oyrCMLAj>_`7 at eX!`%Ts}MAMM~M)Sb69`ie_P__r)%qZ$N<9osVKnQS^L# zWP&amJnAmcd3zU^fZEyzCx at HwE3HOWhE(!Y)ys^rMa9JEqq=THbrDcf2Ag!pq@|^y zp$O>ct_6v|LBqfl$sfY$9kQ&veperLlL$N6>p;VxR-A#0U&Z=QXJ}w(C{li)e9tT{ z2Dt4mq<#AINk~oMo&PnuFk!C~{lRQGiRJf|L|mPkCeQ{R{m-b3y)5NC^Y5`-mp;#k zNgle0ioR)amzI_m)yYzp?(grHtD+z$mt>0$hMM}dzdr)i2NUDBSgchYhEjxxUS9Z- z;Lf#VUa1)`;A9zfe(CaMrDxBcT`6u66h7M$16|;j(JOF5R6_=un4wW_N|99z^FfR% zD=keM%6~pss8yZY)RY`XD^wI$HRU+-8BLij+VT9v$sIxq8x>0ZKsmSG zb=weK1Ro#2!lau_nS~@%k;Qy>;fJxEodU{yc_2$%yuzRj6J11DSU6KT4 at ytO`}fz- zQsEYS!TVF0`s>R(wG-8 z`O%oT*G1?&w_Yoq;9z6Zqbgqf=`>wkc0Q5}qqeAM$jz0K(iCWEX}RP>L`=LtK2~8t zjF#Hhr)V&CwEYJgRj6GX*>tkPjxM5-BX7fvne_Fm6uO9og at wD5(~INN)BC4&gh~tOuP}|VuUT4J$Nq?7 at msdUe zl)SpE>RbCojVeWiUjbZ?*aF{dmzT6){lmV zhe4 at Go1C?(6E~>m&{0r&Q((^HtApP$>`8Jb6GKVvN0k(;W$TnX9U*Y9I|!TT<_p#=jS* z>XnwH at EZTDqcX^Q{WWK2=cD}*Jta-e;H4#V5_0l)G|JW4{pMT0-*Fm_m6?n}HiKYw z;0N&{GI`kb<;#`kzZZhCa&ib;WM*dv!v|EAmES;Bpl4;pu6Nm7D9+uOgI*n=w6(Rv zw1q%X#WwKfk4ZJu%{WH_ at R!T;uwa#f(-^hs3*}Nbc8UHXS=>Z=;ker?E z_Dadg`878`nsWVvmu$Y}qsm6wbi6aY{;8tS(%LGzwk41S{WsWO8G?4B+b{l{r?P86b8&Hr zU^KcGjId_;RXVoF48Y#;eAc5rnVC0 at jg3Edbzv(AAKy%N{f*t;-d?dnB~ULAD)AQ7 z34yqy?Jsl at adFt!u3eLjOOy5Yq5RB(7xVBq#eZMe)ImurPoF;hI`06wg6-tg{9H{kV*fTRQcnwf<G{ zT3QBVNf0-nf_srM85xZ3`zx0 at IXVC1I)ywANY*#?t4g< z|F*GodrHQk?qksAPr-3I|51;Cl=Lzc6&0A>8*FSi6IC`=Dh)8h>J6 at 3{`fTGpK9R0 z!PkV3QjaBqxQ5r!Qsol(2vIAa>ixn38yhD)FOC=e_%?0p^X7lBvasB^diCmf&5I1( zF|!n}?2+V+Qp1j5wJ%mn$3HZ{zJN+8D=8^OIk_TDmMC-C)Sb-%`;>Ia54%8PL zAOAZqC)u*%;r;vMn+?18D8#|AaB?Cs0pf8975m6r7;35}shz(54FoSE at STahi+xMV{a~B#X><(Uj zn*zQ7<4di_xOsSZu=aO$cj+Ufz&~CqRAc9O^l~AjZvlwUcV4rQ?BL)aT8Rq!E#97 zB+{&N%quzjnWu8er=g+2*F>{0CR;vf+}Qi^++I#m36o&tCuPTmUUKS;(WxQiyloJ^tlVA3eIrJ+mGj^&Uo= z&g&?|v9xZA|6D>trFdUF2%~<0e&xy)>#?%S0K at PFjNuQCM_E~U3o86o8>rSO)T`6= z`vzkmcZA at f!ovv=Kd4 at mPfSI{&T$Ifv&3!J)YZeo2tpbuEizf65)zmaA=h6Q6mXoK zPXBEx9;pL&f%?px;`t^rlE|Eg@C3yt<2Z&{P^-E0M!S)xeQ2?W7m8hw*2`F6M8)_^hmwXT(Ve-64n;tdy`?sjLIPeY=%5iJvv5dSt6RHBTmVv?H#S41W zhlB+7hk8s=aBVIwdSYVYNSUmg(K6Bu5m+zcB at A2kTBLZ&V z!40OHyh^I7I=@CRayiUNeKqD at o2b6_;K2iy+qeC4a+p0mJ$)Ak|H^Y&@KC~Jf>&)^ zZg)}8HGelcs*bE^zsk(uje{%P8B|{vKqOA5@~*QPIeSS}-ERTdIU!pX_eCXDV8?dnLeq=5nbPfK1Hf)~pJw-EMf z3%J%?JVHT36B8Vy^o&; zbU4p{BSnd*tH;jb*a(**xi#ZG;%NFKerT?eAWK;q)I?5x8)7-@Yq>Yd2`zk&WBh4l>qS6#>((s_jub8*&<-$K+2FCtDk^TWv$Nyi<7a~sE#0D~0enOkX#~$(_PwnwqiZxWDvDKDI2n9Y z*Z1!skZCL|EP)F>NfYL#T3XJ(yf2QK8 at F1o&i(l#1`%RxVQn0+gK*zh at 9dxRxs9*qD zeuo*;^V*MY5%81?;OeYPMHnBZU#r at dRFI@)xKJw%%$WDZ8Ph7V6H$8SE3&%Lbj;Lr zabi^}Mp&R-OJvu$Pv(BOF=BcAR4vwRBp at cvxIgZ8vYhh-T6G0^bEoO| zSbFV2E-tReApP!pOY{z^YX+TQ5Ny|gx`-qM#C?Gx0;vf-Mv-MPs`ARpj+z&LP$&?R zSRkjbgrxyVd825KWPnJm8J|AkKvX_^_AGQoRZWdAUf0sV04+|I>CDE^5FLmcXs)%h z6BFT|?)kg- at 82I^)tAjuPRq{5thSr>|93$Pb-qrHVq;^QSzNq=+S=Z3nQHVfu(2tu z{_*W!i!jlUltjb9!Exhbcj#{VsMw#hvqXHtS#UIfRFdH7z$@7AF38O)fklUKOoL`Y z^Fa02`dncS;B&JxGblkp!M&BCt571B`ZEHy>dVXTK`i1y7K0i%nLjMB>a)r3=;#30 zB&RhoF>!Am`S~-osHjKZaM_%Xj}O_90{^hKwl)JchMAd}|G|S6V1c8F{(eHR5555b zSG2XY^)0`BX_!>{C?_D3MMTc2EAH&fcSonr_w3A5yV0HW`1lyvO!M+;R2+eL94$Ru z8za7R=Z?LzvwvY>VK{CY09lHnbKJh&0i{_{ON+h22rhsa95=U?i3zHysi~#u=0`AU zSKyaYS)OVY`6?_VH4gJQ4liH&*&M(t$U5SS7hFX;^~2^9+`POt6~xURk{i%nD=Vu; z!obi_Jh*{@kr9T7_vz)0MBRH_TrJaoFI+fu8?KX)k+n+wwXHLe$x at cG-QVAD4g3Ti z68H at QgoT}*IC6FpduPK&n=QJvqvNuzt*!mbmv8Iq1+{f_X8-)b(9_e~TOPd92)^vI zi%(G2ATtfPab%;=*!af1d&HnspP|-;r=$R4Uj>alIy%A@*VokWxV_Ko z$%NqY^YeqUD)RX8>u`~)I5_Z;_uvdsV4q3R(a{MA2z)@P8F_dR*0y(YB0VN8 at fZTT z2!{3Rw{M~_V=yF$i-pQCv+yGUwXx)qM;2VrF)+C7XG9t?M2DRm>oQ*+ z at 0es}Wz8OK|AEZEB%dVU7avav&UkNgnhwgzKNEJa{w_831`JJ(7VaP^&gHW5@`$9Q z(5vKkZh#xt(9l4pkcScvaSODxVOv}FzJ7iNM_aS4fuT+fptgVDvq-m0O_{jw-FpG| z%pI~+*VJsCp4J{E{*YBb* zFmXi`6$wN|MG2^>f8D~rTQArj)syw~qy5}hLTX{p>v?&3ENpCVWSPYN-FPJ+BlCyW z?5&O{Y>HX0^;`-BdjMREK|w)*bQiMX5>z^n&Gybt2B0OdGMMHg0Of&koKbp*6^P~L=GOXJ z#NEBl-oL%42Om%- at ZCExD9kX#NAbB|Ln0lKp#YzUxDqLOd4J792}egBCfQgYK-wt+ z0d**!VYEWQ7+3I-y}cU8Wg>`zy9TY7WaD|TfgSxJ6Gjc3DS at r{?PpNnpzOhXY1cVo zJJeDmHv|IhOB3UA-O`^$7h3fM+UrSq^d3h4>|nwU*(VPU4xX8t^No$Y{?F3VJyYDX z^Yae;%8BKYOqJ))1CZAJ=?ooh_I?D^+8IXkPCAOoU~RP2^OL0b$2&T$VKjmzK*?tp zr<*0^h- at HLb_ICxH*F<1~krh|ZBl}sb2i)9|lG8fc^73K! zHzFb<-%#DRMV5eI)LZAeqChEIt~5*ZZAdS|Pe&{H#U)OwYCngEe{X-GlN1$2havhb zIhfS9zdC{}2s*6}Bm4eahlgL_+xEayPNBWS8Dvd=xLEH!va6n>kRtJ(R>-%1+UUK| z at Y37nwOLVdWN*I8ZaQpzqM8x(y{M=tmj49sCA1Je_&?(A1;8XB&T~-V zkzDh|2|F`o_99e09`6fJD0z%|sxojZmi4K|gbK~V(KI2F4Z-D`%*=zSkKanMMGq8c zl+)HR8agkg8bZABK-hreDzz45ThvX+ftjDnmUVX7ZCSbR#t$0-`U=# z2b$KbFel{Y;R&QsE0<4xC=FrFgyMmGI)TZS&gc)MAzMxFNqiuNEIz2HsO;?Qq{F=L zeq9u_=#1xs4!MMLZ at e!h5faT_}22}dNfvl%p- at XMiFfuN~{~88lF2aEFxNK-6 z{c&7U6mVP$AEhr1kb3n>__)rg*V z5($o9?smz>TN(5R>=Vu&F6sq7dkmB)|K z`~m`^8XJYqPgaX1Hkx#HmBW`g1wb+*^VLZU>~);{n8MwVEwE-4B3 z^zvfm;rRfe6*_*{Sl1d>&q_n+;Zc2jw%dEvW@^$|r8`tEPjvt+N7t`kiLZ|5$(0P3 z*y23{$Zl%_IXOFmS{Ze=)#XOBKaZ4U$^c@%p4AK at N%_$A?h^?KWfPMur4ws>=A5hmvqk*%d|t=mk)fR%B4!{Gm--h0VBJAA+)F<3xLfPYVcNrZhqR4z>poca4w7Tie)J9ITBwo*vk| zl~k-V!SQ>e>%M%;!O`(1F)?x4S at ra*e})`bC at wx82^pc2r3_4FiKX#R1qGRL_sk*z zJRdxG&>wm0X<*{Q-EpJ3Cm& zb}H|Qc0V-Bk53^*_%_FgIghcKnIsDExL8S>iqAR~GyzzI5l9RvQP2r3J7e=D?@!3S zH4?EnSFbYGYRiL-om*Lvfzpr$I#uEB#WS)vY4W3TNSV$MLYmRr+Z!@GVl>TB#(h%} z#5688R?*V()AenF{-j<_0In4qSz=~+YrbVrwY)LBv#9_`0T3Pv>(z}W$M>0;H{n); zS{Fc~)otVEPyZPO_v87GtbBY`VyCfOMwoK&NwHJ&cQMXBGFeClCKM2plaH`$1055h z1e{hrlvsB~-hz~tVuiW1#^0l{7Ueq421{x8su&z68gI zLPElS>8!6Vyfp{lE1qTM+9aRH}F)=e!0c<%x-}Gii z85G^j>1og&WrLY2*gM09jC6mS+s#<$1{1B&topLKW7IFwUVA9ISQC?Hv8zd5oI zkDRkG>I|`PN+^^QxIMHf8?;~xX296eQby2agGBIyyyWJj`{{Z$>%)iIA?laTPxcv6 z72ba at B)SjRCq~vVYdsEa->%;R0fJP at dtR&yA01!H{W>r(ps&TOkW3OYS at R-eY~G=^ zVRE7-B{sqRyb~!I=zRv{%H?HcSg0gHmm;z8X1yQlXa8N1wHdDn@)2|~9XbBL*JS&X zq=~`7AVL^_-;P#8QxiwBZ+mZ_e6Qlc<-o3kuX3k at x{r_65rLs{0b1&C9_3I!eGE#J7W5azOZj}W?tXB9w<{Mp1CNTwt zv|ZzV%&38*fV*DQNV%E9hv?|Z`kJSA_p-F;y!HqKv5*b=JGu>lb#(#+gsN=M%55Nx zD=geRs$Mj6x%hL^)W7(H3H=D+e*XM93OO4SP%%yMkKyw;lmHWtcx12BgO>4eN=C`B zb{Hr6sIC&bY2mrKxzvgZlH}y%t?g~XWQD&8T-p8Rsqi&qnKooe_2Z_Mxp__TsG*Tj z1Q at -xfNMse>8=ZLX8LAk0dRFgfP-rXtuGd>vgycx)LIX|Z8+GGjaOQcLmPSO`pm8C z2CeGG?h2e9ZrTkh5fDbi#ZjR3)!$dvny~ENxnh&iXh_!PGVLV^ibUfs*9Un(#;NNMvN>-nT02v2+*r&_MH(z2!?jP3H$%D`4S-E{^_)j at 7*Q1Ey4p zAMay$c;8YjSWg>)%g3n`3bwX)&~C)ZGI9K~DA_gdfS!8TvJ2imz%Vm|s&EJI@&0n7 z7L+Y&8XAlB at k$2YmtPX>nphKEgaJ_VRM`aJ+wtjXwOh{W!h!_Ke74n3RZUHzva+%Q zW>TX3kLF+uSCqU*2Z#R`T8|K2*I7UO^*?%lPspJ#Iep^PUmYuFMoR?_*4R8%`~NyG z<9F@;lu(3E;L?O$^DR_s_4cca<3-W2U{ZE06rxqo*VB!9iC&#@Q#>>mrkDb)>aZf+ zMj23oOjWjJklno>_ow?x4BC88Y{p)tr>C0(1*)p6OIcRNf9vk{bKMYrGWzS}27`fU z+r8e0Vn_{9Wn+EtAg-aYkuEs%p54?#s7>Jzf-;!Xh29stDI_E$H^(`02L_Z^hVnm7 zx&6T=W+Ff#s}`!wwRmcZ988`s^Z$?2u0seZyek at K%k8&euvA13fNvRf zK3U&bVRC9w)CfFQVfjBx$s<30t$vec78Fc?{5;0&lDm6k3;DUTwUs)e>+xfB8w-M5 z{Lh#7%yF_3RaI4cADhpfTrU$46ukdw;+KDpTK+QK-=iyTuCCz_fcwjX0c3ZyrS|vt z|I-6i4Grmwi;KPA?>H&5np0k#1bzShUEs$^#&b2bfo{%bWFw$;xxapz`2TN3n#aw4 zad!4GD%WLmN-hRzLt;J^(9 at E`byi;DmnxP19?KL8ok4{NLLgWbgx?}4kF4aiwL zq;3xn431$b@)ykE4X-^ruaEHWPd9BD*syyserf`e0=;pNP{4vw`%$S7&BQ} zS##(m=A)}^>XMp`?z|u#0{|UM00xEugUgjG#!KXSo{yFDK0xYS&cLJcKHvZ62-m)? z+Sj(>o>?e^B-GThU@#pI)-+1n(&pxj9h{w+9zA*lRqEsDY>Dj+X667Ug=AT{2n5CG z+ at AfgdVcX|o9U(`_k%TQ=tcSz?uVeKg=&L{1}`iukkHV`!BiRs+yrBhZI-{aaA at 6^YA_&`F* zZH$F~Gr4<1Uq^P at lSNeBraqgdG3f`^NAy06F- zXh4AAQ}c at qX3H@?efkuXH0}MPi&!=`Hn6JQ9y1EhCL7$M$T-wR0QPRcJL2z|$p?5d zBso!sN{BU|?Y!H{GJ1RES~l1|=W!Jan+T9oK at Ja&lfQx>QzlA3621 zuL&Rd00c?{Zw3-Fn(wa+xgS0 at J}jOT{-&j(B9^aKnC|0)0{2HkO8NwT8aTDo9)6%x zWB(c%jQ^ZejAD{Y7Yo1-qEQO~;L3cKuhtJm77JBdUq6Uc1dqdw`Q at X@zOiyMi~jT{ zBxGa~;KC91e0xp!uB!+A!OTr at m&wfr8UjM(Sp}!nVS|Y(8*_8>&zaIucfC#=A3}LA zDJ!$=-5A9{*2=1ECxh{*_-+UZ(M(NENl8h4{vLO4c6F8A*;NABCOq5e=0x at bfgf&s z?B0ffHX6v3M$RNboU%Fx79_Do%TNoslhiw}w;rrdL?k3!wX?H(xZO at 1`_PRW(40Pc z#cTDd74v$sH?ml}NukBoc+?W2c*wXCEBtJIFH%>8HG at b29bIlZ+n0=nSa z!{{D`?d>^c=HxKmzKsV6iJXdpzRAfBp8YHHet`pS9cv4ws0E4M$f>24)HIcuYcp at aPu1Y!cwtUON4|w zySpGOe&uGpI6(_g&+hW_c6@$~K}bOn6u~ITaOV!bt*xzL!1o)<1GOXT6V)%E4Vl^5 z47|Lg;KAN#7W$W$-$TZimNu-U?iK#~vo%*w}bxZLD08 zEgD&91b`$YCVmSOf=m1GI+#$yfHTE@%gP$pZH9rtLBFI)$O$Dqy=%~=qvK;KnVo%|ntB8G--UMM2qHQLh5>lb9d`Y~A=aocdM76* zWB~4H*W6h1K^}|h{>XWiDzmWgc0)tM%>4Xi$Yxh}_tv2yQsmTGem;9*Qqt_&+Ar23 z1AtnD2mK%lj&OZsRmPErm68#z0s zp+SK_=Cs|fn%7n%MQJrP*TG{;LN3Y3$oQ^nGemrDYZK$-Iz2gQ?d`n=)|jE0`yjPW zcECbLOblaZXUCUjA2|h?lEQhWqpUozltPK3rly{OJ0geY#>ODyF&%2D;S0E~q_Wa4 zCgtNsHPGGt^k^(cfv%>m&bg1$*l+;C_tm)okacimBoXo$-oKl6ot0K2 z$b)&H-suGevYWLrF)^a(Wo2b=U{(qW3k?hm(2x^n8X7GF14REGM+=w9f;1Vl`mBrl#ie zj~{qo7ww&#`~m{5Kt=YOYV^oJretU5ji28Wj{?nMX{Y1NK}uwYSb_u?`JY*zZo2)@ zG3fC}7GOV1D=Q@(olwyJug2WScBZ5;3S@&SG~U|UTHn$V2Xt0lORKG?2OkDDynDW+ zs>&Zah3s92)F6sN-Jz+e8C+_qP7Y=eFO1sp(dxZBm$OGihNSBu82KDLpL zwCw?OuL1$Mu_50K16oJD>g{LIAu*6M$sx2tnrrsz_dCfkG{d8!25p3sdTDj1z5fb< zb=m&P_&$&ZXLW&pxnky9H2c=!A-N!K=SG5NVW&SH)m@`b++ at dA@h at 8XS6wsP>gqsL zkOV0={Xry1(#gNf0~k$BN=o{0z(8jlYA14b5INT?W)Ko3|1$X9J2VtHT(Sp5og2Nt z9b2o#&A&OlkKc`^-Np2Yk}rp_NAr0U-dR at wueN^shNF@#O9)p+o^MivX+ at p)-o88h z%=7R0q3cHN;*qd%!Qf2hU`TK<4n)g#z_|Ly56Q`4FBf~Z^LU5z;8POtsrL@*ANS7> zrx{sTup%NNU_ at f!X7>P<_?JuWDhZC?DE-}GQ$6o<-fY>pR=uw80yOdhw`We%%8Hm688McZmtE(hpSR=t zaS0_lUibKloFbv8r at zi+=nGxU4nQ7jizqAOKHF-$7Axpd1iv&z&T!B&K%V;n+-A!s zu{pDZP_#?uPyiH%HigBP_Q)2h{b~Mt&T0BR7OhtMjx+ziuglBJV>Txwm-d*i4i|py z?rzI3ZbClH8w8z$SnHAwaH3#WEBK5YHU&0^StyXsHoVdox4+bn0itbUVq)*$KqN at r z8Sl6@%0(^cjO%@IoCA#-=Ad2X5&LNFsQ2Qtx>=>;vNA4>013!FDNIIu2i&|);pHwX z-*B8xlP3kx^gj+C?p+xO_jY7Vg1Q~SXi#8*9FT;f_%=u)lEyBr=Gth zm2(+{36z8cf^!dMY6foK0zhv72?E1YiSyo3li>RGKv1XBHuFpfN^ETGrT&a7naZp; ziLg;K;B{gJoY)c*6M?$+Xbm+>^wA)|nJjVrjm^xAwtshA7jQJsa2g{6Y3*!q+a(|) z!>rZDzk2m5sPAm_bKS=V25Bve$gt3PZna=^G+B>vLoNU9N3M(Vk>3`k(lVPYLd|^C zdxc;LQXY(q-sa}ASWi?H4)u~-)vwsM$2&nnqKnMW&&v&?iF9g51I9J( zo)QQnU4B! z9sIx>W20_sRs=%s=Ya`Fc2ZDZfBi}XrPs2S3|aqny{?z+1O=+R4CTVM?APeuwYrN9 zdHzC;JN^)QQL;=KT~W+b9CZBlH*V`T#Ny!Kgiyyd9q1~U^(4}x08dOxJX?LSZ+`4X z9tM(I2TzS`&TuvzrT6b_d~nnpFVf6NP4yw;)RhI0wf^!o5b;eY#3s9&Af5=dcX7Ho z?Q%*}sY7uULf9`&EZ{f96K3~@aKO}0UXsb_p`oFpiRlYWW at hHt`1qCR`$J7dYg6uZ zRs=t8+jaf-9QADCHiVPnvuC${D&-Fy?F}jr($eCCEXT&hwSYuzZ*NP<%iC6+|M$Q& zW_NFrU;uJ}4J=GxSXk$$XZf`8f+B$D|2!s#8}p^JGrg{k60C)_O8r&xJH81CR2K); z%@iEZSx91qJorE?koW_yO$4kQx`OO)gBkJxC4>vi_!Nw*{Lfi{xjA3tN!-5|=kDuy zLzZWYkN!S(b>*LPcwo#;0eDT-QK+0(V%$aK>+dhh6!n-Xik^puq&w!e82poQ;5d;D zV$te%6?rrRpc*+F0>#Z{NWk2p-crWR?SWdMrr*+%xvPiApCp&5mfDw#<3A;yf at wmb z?wNk?V;{UN=y|l|RXwdV5#1k{v|slIF}7!CXSgwGq$7%s-U`UR%Fe>LU0(5m;oYB2 zYWZ2f)O^PcK!Tq>ePUop2UeawtV~}X%ppbz*w6U1?9d20_m%ewKLsl!>S1bX%Jbs4 zxQwi<_4d!M^Mdy=TG{oU>ZBmPXbZk*8e2qa#aTB|QM0*eJZ~ zcTd$lFHj4N$w*^UR`ZHCW_wg>Y at jG}ztVEk at 1Eo)t-P;C&fkCmSO^_)X(Urt^g ztI)xyQN^oscV!k5xvIZ6CZg|@P9~WaQ$MWl zW);=5FVgcv1+%h?Qe0&ZDhBx4|a=Q*+X|2cztc(|HQr${2MUH;#?(Y}6 z=)8=QH!+!~`rB9+8J3ntkMa2uIvO$7rI6mmd%`Kbt`C#T8WmZLL%3q%jO!!AtD^#>(9UQ3>nk-4&4l(q*VnK5;HGg=3A|Qnjf_Noz;u{C+s9{2 z)6egGEN}8U<+iii#GGLH?d>H47DV}0+}cF7!u)h?DWgjVOLeKz>!v1Q48_f$)twy& z%-rNXwLSW%F3Mm2**ukcjmeI1n=z>FTDO*SjojsQPD#mGmU#xNY$jq$OSz(?ZaNL~ z-d}E5c8`fAtoZNAojfi}W+wB$A5 zXDJBc{n6}NX-O{LO8Z$+=iLRl`R35yEDe>B@bF<77MKlOJ{gYHFIf|CpRi z>S%AzwQ;ur-;SFr_}e(7bZ*WVlgAE6>2cD3y7TAD`#6ys`cS!?hFQZXsRULmSKehF zDL1@&JaW9dI27ZEiBJ6%RRTPP`N#76WW5W;){e2Y5y>NakemG?1t}^0rlzKEoTOV0 zzVoxQEr^a#)3BM#42;#j%;DDPNw{C!MTgm`8?%Nk*V{-=LQ>+qK3+OAGb1s<`rFRZ zU5 at K~_vG3E)cF-pOlN0jT+~FlnZnz1w(OA=c2r-6ZT1dKgX zgp|6B49 at C!W&U_%4^-ysTV*x$0s`^#i;MSQ at Bkp|!5F>^4mJb?58>+6*49>+mBnRe zVbOP}O^p8Vp=7i9Z&MGUwHL`V3A5hhLYGDcKHB$R{BbE-85kMI26GgsycC>{Go;P- zSBAbd>(tmAl>aTNeI}u+tNXpPGkZ$uAfJS552OItg)2|>8)!vbWhF1hg`QMj)>Cp! zpUYRSl>h#1sP^nx2N4m`hsCS9=eSL$8-kcV6jW5 at Aa*6lt12pO?S?O41n%9t=M1Q+ zrliyYu4fdY{sTGp$aAT_Q9homyz@`=3Ms-SP{*vlhSRgDgxp>pdM73(D!S6hzt at u_ zDA)A9?vTAmalj2jtJ>B?LPBBj61TQAbLc)!Kfiaw;K*wh{ z_0Ys5L7l at CfJJ|@&dEqXKtT2;QR!=pD`g;>BOb}~&tU4l_w|J%yH?|2?AlDovlUE4 zL6i at xx6Y1Vni?3iWGkdxNK7cJsda)kj|&RICJqw+-rfClzKR{<=(b){qK3Nq-899o z1%-tg_V#!4^YZdsP60-=%1!ZBM~dkNM at Gz`OCTJdWS>gkBm%I_wl>n&{|v(SrM0bX z`h at 89iTTN^j?r!mOfxexxP7eDO~am^p0%ynw*4xbALqeV9~`F?_4RL*S643zgz%Yc z{Hld!D;n8#w_NTJDtq(h4W;!x?+ef2G_fl^*;KqV>(8Bd&6JX z8wl^;zrVDy!obQJw5m8BV%L052J_;l&aogs5<0WA6iCP at F@ya50ZC5R=!B8K=m>ep zTwGG}C4tVwx*z=!-5Qtgr z0CA~z>6yD%9taAGDJWcnTg?lQq(1 at 4ECJ*Q>@dW=e%EK!9?Rmzp84BH=Ii5?{4N{R zkpG=dEaFeK8(awy$ORO>MV(%0p1Dir>FH^|zw&HuZcao`FJ;wUipu%#g%>|R|L3VG zT0j+>;qq`Si+3!`4SrXy(ITsVM?2k|rEs&NHhLRX4GjtiVHAq|jFnun!#0i0IM!R9NVjk->{P z+uMCt!vp$O)v2ps77f29+o!(Q2b#3RWL|Gz_P at wm-f=7 zOZuk=>qlq1y|wrO<~~Rxz&L at q41D+Qt;mfTft#ZIX>CrZ at vptT*Dhba9Q*IXEi=o@ zT~1QIVj3D6$iZN0YHH-X2GV~CMjBq^*k*cq`VwV`%P3SgF56%HHFb5rfg~O4Z|?MD zWM)W&a2=hV{(%|b_d5B%TDa~&s at pGqjqH_5GO}JGD-mzVxOmNLMzRuRMcJz)T&~TP z8!da3n^hDcn~acKq(n#=$qdQ(o#*$ye^%e_z0dhR=QEz?oTKn#VWE~St||}p-=iBN zrK^0v*MbL`;BPtl%!DF%mV;G)e5j<6k&!_&vIZ#>^nBXpW-uzq1~x=Vjm&j50BR zDWSaqyg*q?tNrRqHEL2)EC9osf5!KclX#WP&npO(=N3>5KtutbqEn#YkdTYRW%iH_ zySK_;Z7~6tip$7Yh1knvpeixca)^cwz&lSC{!9CrS(m@${QMZLy=~xr>VdX!L}{rstdqXhj!i8)rJ~}*=I`Ilt*tcC(b4F(E=Mz} zhKwDkBR*3#vK;X9a_FRi%V^{?bvZC7B+8Qz$k{3WIZc?&$X)P=)P(3~% z^VA6}_9LBvG9N1FQ9X0U?ELvSV5_E)k-PJ$udhH(e3_h#JS^+*s9uJHA*Z;Qum_HJ zW~@O)_wD|{=cYnbouTVL;!s29m!=4AMNe*|Ed%tv9s(sJHd@4#$wwt6$IDuUF}uI}!zXul{yZuz1zBJu)(VQI!sX39 ztK`Jg=W#{D3cZjQa+kXg`p*ndf!AukMMYD?rjNeh-x&ju at ImQ!?i?QmvNAgDd*b9t zbB8ywoN*(x*-Cq&B?8GMQm1!r_369Wven=V}6rjE(O--tm)z#%M%{1uL zzP^6D^v_!gB?|nLvi}SQX!OQXGktd<{NkCs6a>Qw$P*kML z-t&FF(XcUQF{b$<8UpozA zhw^4mu^!_}SRQfB&VBik$IQ&E+jX@*c$s==Xs9M=@#y9aHJ82zak%@6k9X8A=;-MD z9WZwgAVP>M!DnYH;N8$r9)z- at x>{#(tO1SpL!%18fj_VdUz==a{`&p9h?3Ib#_bhm zUq3&RAr8k1tT6$U*&IcW=KIZjdQsjzo~<5!v^9p+!k8?fMu9!v1o0Ug8{<~LsS1+9 zHtZ9F`@HyU6%|Mo#7z77`IFo!Md)G_lt$)>i;>;zQw93BZMM0#fKT;IOmxl7In&b8 z(B%#6GKflvl#7dt^ic6jbV1Zjl6>9W9ceA~PiUy}QPp4!Gc$8dT^$--=I!GXQCoZZ zRz^M#KR-VUuObVuvIKv3hbSD%P+DdI-oGl6m+(N?z zwFqnt?-`=xV%FCDe~dQ@`1tq)ug&b=T3=ue3JOBs0m60Q{d=!C+~g?gqImEiv7q3u zg2F;gvD at er4MMjGuMYK^)NhPkwe5OndP5IDJ*g-B2R3pnSi}L;;pX32eAX6qXLPEZ{K1dKN=_&M0`D?fwI@@ z^2XhGcp$%`f&;9F4!oQ!)etlcfn?h$&Jc|~(UJaQYH_qyzJyFhV-`RLDP3vP=DBnC zZro|VZ>Z%E%`ZZu&q4(S01ylEMIGvcBZ^J3OQawNgIB&Xq6+z*4B33Y?|tZe6r{`W zga>P_T{0>)nH?-dl_7cg`JdWO8REU8(~`MBlsBhKSa|>VAcrRqrpm*2B>CgW`YtYF zVkTKEKxwcKKYaM$&Ce;s6PK2Jr=+B$1 zEd($KrTbT#q+Rr3l@ z^75#Ylan`Bv-c7~o`Cezb~b(UgiAtFvNcWAu;S`x{RQ>&D?#AIw2j6l+d}oGAc~SqD zS^htdt7Q$8-y9?AIbOaT4O*i&Q!WbhfW=G0{iu(rl!XD z)9_(%`^kK#^E{7{3`QQA<@0#9uMf`JaFMP;d^S}@JL=AiAT^3 zs7cuDsXf!;Qc`V2xcg1qT6%i1Pwlm}|KFtv(hrqM1#hiM06e4;i4n_FoirHKO;%N< zkeQh&sHn&_Jv}WhE898NaQ*G8uMa`9< zdQe%d)ocn!Qb)j$$hGn(PZFsdkC|k7l6IFGiCACXr`_}L$4eONa)*ZW^1_0G3ZJQt zO87-`KmsIU3?SK4d$4s!FwcSQ=>9B#r=@8EAUWsyIqS at IZj6ho>$zin at Eb|bHx|cT zG1ed<$AUlYiHnGctOH6`*+8g{AOCBB8vdD3SSZ@&B*(|k|9&hxFEyv6gbBE$dzf5O z0^%sAygX%Y&I7TBMUjzv)fbJ*KG+11P_SwOk!aT7#md4WNYpbmGovEv6+AUw{y-0Y z|E#6u<2H%gU2|uXs{`fmAX?B+I8nnpRp>Pxzvn=q=2r=%P3dfHC9s3}1zeMC;%;q; zX7*YAh69-qB}e!8?8g!xZ~KyMpl-xC0KF3mY*+;Y$x51Esb~7}@MS8qCDR#O6{fdv19-I|dx7-NOy at QBrLsv&12G0~OHH4+FqtTZ9PU z%&n~%?i$g77%S5f!utU-pnIUc2d60|VRZZUp&}g+VPJn4n3$+BiM&c|m;rG0n5Gg- zGE$Zhp1;JzoIX~$2aNTMj|*T5S#L#l%>JM%7X%6lc&F9*fL-Dw^t7M{EB1_f$vP za{bpYONnTgAD6qdJ}}C^F0Ew|k~Nf3HmUwzNbtMq^#P zyxv4cMV-gta1H8P=8w}$&p(R+rI0c^KQB+zYXg)xkHtoI2gXE4OMK$y=B at xOSGlz0 zO~S8wJV^42dinWP*nM=unwZE^y`iILtMUGd%_Z2p5X=@}CZ+=i4ghlATDgaAKa)j- zwB-TzgcIfdR#8E0@^|o(;F){(oaN-?kRM%HSxIj{gs-1}l&X=i^siGy6Vlw=#D^#9 zDX3-!%@_VP_dea5A!J_?pgaT;qz7sprKO|utf~0f2bP2zYnX9R{mqj3aTW(mWK^`=A%tR}pb!dpIE@&~vRQxO0Wd)`)mIj8> z4)xrSF{rK#j^y+?q!(LUc?crjkXhRe6KvJ!?*J`=ju^xp_& zUZtyF5 at cWHBzQB1(D*;>Q!x^|{a;fy*osad at BIf4;(_oY`irObV^Benu!ufTa{zA9~kIYioEQ+~JFyc>&_HsV-ezU7G(IhSaRAWZ*9U z#W8*mJm5Sb6=_0$%@q>W-+{A0@%5e^6h)PU^704HmDxoYiD`|$3Paya6wz&IZ`b*) z=Y@?8H60YX_5^@^WMl-{k-$JjKzvYv)F8BAXScwvZn(bj->_LncXviZL&Iu^!hUWo zP>Vl5*AXHksYh%5=utJ{%^hXPLO^_Q{q)G>oj%<>GIE5CjcsPIFyW(EIfaL7$?RE6Ja|y!IEfnL at 9&SqkXqQ5cm|L# zB=fHgAqiv0HrZ$Y(n@{E3JPYcuTb;Kdi}tWe8E)K3tKWdQ$O$+9*7W(bqB7F2g!T F{tpk90)YSk diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst --- a/Doc/library/distutils.rst +++ b/Doc/library/distutils.rst @@ -27,3 +27,8 @@ modules into an existing Python installation. You do not need to be a Python programmer to read this manual. + +.. toctree:: + :hidden: + + ../distutils/index diff --git a/Doc/library/packaging-misc.rst b/Doc/library/packaging-misc.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging-misc.rst @@ -0,0 +1,27 @@ +.. temporary file for modules that don't need a dedicated file yet + +:mod:`packaging.errors` --- Packaging exceptions +================================================ + +.. module:: packaging.errors + :synopsis: Packaging exceptions. + + +Provides exceptions used by the Packaging modules. Note that Packaging modules +may raise standard exceptions; in particular, SystemExit is usually raised for +errors that are obviously the end-user's fault (e.g. bad command-line arguments). + +This module is safe to use in ``from ... import *`` mode; it only exports +symbols whose names start with ``Packaging`` and end with ``Error``. + + +:mod:`packaging.manifest` --- The Manifest class +================================================ + +.. module:: packaging.manifest + :synopsis: The Manifest class, used for poking about the file system and + building lists of files. + + +This module provides the :class:`Manifest` class, used for poking about the +filesystem and building lists of files. diff --git a/Doc/library/packaging.command.rst b/Doc/library/packaging.command.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.command.rst @@ -0,0 +1,111 @@ +:mod:`packaging.command` --- Standard Packaging commands +======================================================== + +.. module:: packaging.command + :synopsis: Standard packaging commands. + + +This subpackage contains one module for each standard Packaging command, such as +:command:`build` or :command:`upload`. Each command is implemented as a +separate module, with the command name as the name of the module and of the +class defined therein. + + + +:mod:`packaging.command.cmd` --- Abstract base class for Packaging commands +=========================================================================== + +.. module:: packaging.command.cmd + :synopsis: Abstract base class for commands. + + +This module supplies the abstract base class :class:`Command`. This class is +subclassed by the modules in the packaging.command subpackage. + + +.. class:: Command(dist) + + Abstract base class for defining command classes, the "worker bees" of the + Packaging. A useful analogy for command classes is to think of them as + subroutines with local variables called *options*. The options are declared + in :meth:`initialize_options` and defined (given their final values) in + :meth:`finalize_options`, both of which must be defined by every command + class. The distinction between the two is necessary because option values + might come from the outside world (command line, config file, ...), and any + options dependent on other options must be computed after these outside + influences have been processed --- hence :meth:`finalize_options`. The body + of the subroutine, where it does all its work based on the values of its + options, is the :meth:`run` method, which must also be implemented by every + command class. + + The class constructor takes a single argument *dist*, a + :class:`~packaging.dist.Distribution` instance. + + +Creating a new Packaging command +-------------------------------- + +This section outlines the steps to create a new Packaging command. + +.. XXX the following paragraph is focused on the stdlib; expand it to document + how to write and register a command in third-party projects + +A new command lives in a module in the :mod:`packaging.command` package. There +is a sample template in that directory called :file:`command_template`. Copy +this file to a new module with the same name as the new command you're +implementing. This module should implement a class with the same name as the +module (and the command). So, for instance, to create the command +``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy +:file:`command_template` to :file:`packaging/command/peel_banana.py`, then edit +it so that it's implementing the class :class:`peel_banana`, a subclass of +:class:`Command`. It must define the following methods: + +.. method:: Command.initialize_options() + + Set default values for all the options that this command supports. Note that + these defaults may be overridden by other commands, by the setup script, by + config files, or by the command line. Thus, this is not the place to code + dependencies between options; generally, :meth:`initialize_options` + implementations are just a bunch of ``self.foo = None`` assignments. + + +.. method:: Command.finalize_options() + + Set final values for all the options that this command supports. This is + always called as late as possible, i.e. after any option assignments from the + command line or from other commands have been done. Thus, this is the place + to to code option dependencies: if *foo* depends on *bar*, then it is safe to + set *foo* from *bar* as long as *foo* still has the same value it was + assigned in :meth:`initialize_options`. + + +.. method:: Command.run() + + A command's raison d'etre: carry out the action it exists to perform, + controlled by the options initialized in :meth:`initialize_options`, + customized by other commands, the setup script, the command line, and config + files, and finalized in :meth:`finalize_options`. All terminal output and + filesystem interaction should be done by :meth:`run`. + + +Command classes may define this attribute: + + +.. attribute:: Command.sub_commands + + *sub_commands* formalizes the notion of a "family" of commands, + e.g. ``install_dist`` as the parent with sub-commands ``install_lib``, + ``install_headers``, etc. The parent of a family of commands defines + *sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name, + predicate)``, with *command_name* a string and *predicate* a function, a + string or ``None``. *predicate* is a method of the parent command that + determines whether the corresponding command is applicable in the current + situation. (E.g. ``install_headers`` is only applicable if we have any C + header files to install.) If *predicate* is ``None``, that command is always + applicable. + + *sub_commands* is usually defined at the *end* of a class, because + predicates can be methods of the class, so they must already have been + defined. The canonical example is the :command:`install_dist` command. + +.. XXX document how to add a custom command to another one's subcommands diff --git a/Doc/library/packaging.compiler.rst b/Doc/library/packaging.compiler.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.compiler.rst @@ -0,0 +1,672 @@ +:mod:`packaging.compiler` --- Compiler classes +============================================== + +.. module:: packaging.compiler + :synopsis: Compiler classes to build C/C++ extensions or libraries. + + +This subpackage contains an abstract base class representing a compiler and +concrete implementations for common compilers. The compiler classes should not +be instantiated directly, but created using the :func:`new_compiler` factory +function. Compiler types provided by Packaging are listed in +:ref:`packaging-standard-compilers`. + + +Public functions +---------------- + +.. function:: new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0) + + Factory function to generate an instance of some + :class:`~.ccompiler.CCompiler` subclass for the requested platform or + compiler type. + + If no argument is given for *plat* and *compiler*, the default compiler type + for the platform (:attr:`os.name`) will be used: ``'unix'`` for Unix and + Mac OS X, ``'msvc'`` for Windows. + + If *plat* is given, it must be one of ``'posix'``, ``'darwin'`` or ``'nt'``. + An invalid value will not raise an exception but use the default compiler + type for the current platform. + + .. XXX errors should never pass silently; this behavior is particularly + harmful when a compiler type is given as first argument + + If *compiler* is given, *plat* will be ignored, allowing you to get for + example a ``'unix'`` compiler object under Windows or an ``'msvc'`` compiler + under Unix. However, not all compiler types can be instantiated on every + platform. + + +.. function:: customize_compiler(compiler) + + Do any platform-specific customization of a CCompiler instance. Mainly + needed on Unix to plug in the information that varies across Unices and is + stored in CPython's Makefile. + + +.. function:: gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries) + + Generate linker options for searching library directories and linking with + specific libraries. *libraries* and *library_dirs* are, respectively, lists + of library names (not filenames!) and search directories. Returns a list of + command-line options suitable for use with some compiler (depending on the + two format strings passed in). + + +.. function:: gen_preprocess_options(macros, include_dirs) + + Generate C preprocessor options (:option:`-D`, :option:`-U`, :option:`-I`) as + used by at least two types of compilers: the typical Unix compiler and Visual + C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)`` + means undefine (:option:`-U`) macro *name*, and ``(name, value)`` means + define (:option:`-D`) macro *name* to *value*. *include_dirs* is just a list + of directory names to be added to the header file search path (:option:`-I`). + Returns a list of command-line options suitable for either Unix compilers or + Visual C++. + + +.. function:: get_default_compiler(osname, platform) + + Determine the default compiler to use for the given platform. + + *osname* should be one of the standard Python OS names (i.e. the ones + returned by ``os.name``) and *platform* the common value returned by + ``sys.platform`` for the platform in question. + + The default values are ``os.name`` and ``sys.platform``. + + +.. function:: set_compiler(location) + + Add or change a compiler + + +.. function:: show_compilers() + + Print list of available compilers (used by the :option:`--help-compiler` + options to :command:`build`, :command:`build_ext`, :command:`build_clib`). + + +.. _packaging-standard-compilers: + +Standard compilers +------------------ + +Concrete subclasses of :class:`~.ccompiler.CCompiler` are provided in submodules +of the :mod:`packaging.compiler` package. You do not need to import them, using +:func:`new_compiler` is the public API to use. This table documents the +standard compilers; be aware that they can be replaced by other classes on your +platform. + +=============== ======================================================== ======= +name description notes +=============== ======================================================== ======= +``'unix'`` typical Unix-style command-line C compiler [#]_ +``'msvc'`` Microsoft compiler [#]_ +``'bcpp'`` Borland C++ compiler +``'cygwin'`` Cygwin compiler (Windows port of GCC) +``'mingw32'`` Mingw32 port of GCC (same as Cygwin in no-Cygwin mode) +=============== ======================================================== ======= + + +.. [#] The Unix compiler class assumes this behavior: + + * macros defined with :option:`-Dname[=value]` + + * macros undefined with :option:`-Uname` + + * include search directories specified with :option:`-Idir` + + * libraries specified with :option:`-llib` + + * library search directories specified with :option:`-Ldir` + + * compile handled by :program:`cc` (or similar) executable with + :option:`-c` option: compiles :file:`.c` to :file:`.o` + + * link static library handled by :program:`ar` command (possibly with + :program:`ranlib`) + + * link shared library handled by :program:`cc` :option:`-shared` + + +.. [#] On Windows, extension modules typically need to be compiled with the same + compiler that was used to compile CPython (for example Microsoft Visual + Studio .NET 2003 for CPython 2.4 and 2.5). The AMD64 and Itanium + binaries are created using the Platform SDK. + + Under the hood, there are actually two different subclasses of + :class:`~.ccompiler.CCompiler` defined: one is compatible with MSVC 2005 + and 2008, the other works with older versions. This should not be a + concern for regular use of the functions in this module. + + Packaging will normally choose the right compiler, linker etc. on its + own. To override this choice, the environment variables + *DISTUTILS_USE_SDK* and *MSSdk* must be both set. *MSSdk* indicates that + the current environment has been setup by the SDK's ``SetEnv.Cmd`` + script, or that the environment variables had been registered when the + SDK was installed; *DISTUTILS_USE_SDK* indicates that the user has made + an explicit choice to override the compiler selection done by Packaging. + + .. TODO document the envvars in Doc/using and the man page + + +:mod:`packaging.compiler.ccompiler` --- CCompiler base class +============================================================ + +.. module:: packaging.compiler.ccompiler + :synopsis: Abstract CCompiler class. + + +This module provides the abstract base class for the :class:`CCompiler` +classes. A :class:`CCompiler` instance can be used for all the compile and +link steps needed to build a single project. Methods are provided to set +options for the compiler --- macro definitions, include directories, link path, +libraries and the like. + +.. class:: CCompiler([verbose=0, dry_run=0, force=0]) + + The abstract base class :class:`CCompiler` defines the interface that must be + implemented by real compiler classes. The class also has some utility + methods used by several compiler classes. + + The basic idea behind a compiler abstraction class is that each instance can + be used for all the compile/link steps in building a single project. Thus, + attributes common to all of those compile and link steps --- include + directories, macros to define, libraries to link against, etc. --- are + attributes of the compiler instance. To allow for variability in how + individual files are treated, most of those attributes may be varied on a + per-compilation or per-link basis. + + The constructor for each subclass creates an instance of the Compiler object. + Flags are *verbose* (show verbose output), *dry_run* (don't actually execute + the steps) and *force* (rebuild everything, regardless of dependencies). All + of these flags default to ``0`` (off). Note that you probably don't want to + instantiate :class:`CCompiler` or one of its subclasses directly - use the + :func:`packaging.CCompiler.new_compiler` factory function instead. + + The following methods allow you to manually alter compiler options for the + instance of the Compiler class. + + + .. method:: CCompiler.add_include_dir(dir) + + Add *dir* to the list of directories that will be searched for header + files. The compiler is instructed to search directories in the order in + which they are supplied by successive calls to :meth:`add_include_dir`. + + + .. method:: CCompiler.set_include_dirs(dirs) + + Set the list of directories that will be searched to *dirs* (a list of + strings). Overrides any preceding calls to :meth:`add_include_dir`; + subsequent calls to :meth:`add_include_dir` add to the list passed to + :meth:`set_include_dirs`. This does not affect any list of standard + include directories that the compiler may search by default. + + + .. method:: CCompiler.add_library(libname) + + Add *libname* to the list of libraries that will be included in all links + driven by this compiler object. Note that *libname* should *not* be the + name of a file containing a library, but the name of the library itself: + the actual filename will be inferred by the linker, the compiler, or the + compiler class (depending on the platform). + + The linker will be instructed to link against libraries in the order they + were supplied to :meth:`add_library` and/or :meth:`set_libraries`. It is + perfectly valid to duplicate library names; the linker will be instructed + to link against libraries as many times as they are mentioned. + + + .. method:: CCompiler.set_libraries(libnames) + + Set the list of libraries to be included in all links driven by this + compiler object to *libnames* (a list of strings). This does not affect + any standard system libraries that the linker may include by default. + + + .. method:: CCompiler.add_library_dir(dir) + + Add *dir* to the list of directories that will be searched for libraries + specified to :meth:`add_library` and :meth:`set_libraries`. The linker + will be instructed to search for libraries in the order they are supplied + to :meth:`add_library_dir` and/or :meth:`set_library_dirs`. + + + .. method:: CCompiler.set_library_dirs(dirs) + + Set the list of library search directories to *dirs* (a list of strings). + This does not affect any standard library search path that the linker may + search by default. + + + .. method:: CCompiler.add_runtime_library_dir(dir) + + Add *dir* to the list of directories that will be searched for shared + libraries at runtime. + + + .. method:: CCompiler.set_runtime_library_dirs(dirs) + + Set the list of directories to search for shared libraries at runtime to + *dirs* (a list of strings). This does not affect any standard search path + that the runtime linker may search by default. + + + .. method:: CCompiler.define_macro(name[, value=None]) + + Define a preprocessor macro for all compilations driven by this compiler + object. The optional parameter *value* should be a string; if it is not + supplied, then the macro will be defined without an explicit value and the + exact outcome depends on the compiler used (XXX true? does ANSI say + anything about this?) + + + .. method:: CCompiler.undefine_macro(name) + + Undefine a preprocessor macro for all compilations driven by this compiler + object. If the same macro is defined by :meth:`define_macro` and + undefined by :meth:`undefine_macro` the last call takes precedence + (including multiple redefinitions or undefinitions). If the macro is + redefined/undefined on a per-compilation basis (i.e. in the call to + :meth:`compile`), then that takes precedence. + + + .. method:: CCompiler.add_link_object(object) + + Add *object* to the list of object files (or analogues, such as explicitly + named library files or the output of "resource compilers") to be included + in every link driven by this compiler object. + + + .. method:: CCompiler.set_link_objects(objects) + + Set the list of object files (or analogues) to be included in every link + to *objects*. This does not affect any standard object files that the + linker may include by default (such as system libraries). + + The following methods implement methods for autodetection of compiler + options, providing some functionality similar to GNU :program:`autoconf`. + + + .. method:: CCompiler.detect_language(sources) + + Detect the language of a given file, or list of files. Uses the instance + attributes :attr:`language_map` (a dictionary), and :attr:`language_order` + (a list) to do the job. + + + .. method:: CCompiler.find_library_file(dirs, lib[, debug=0]) + + Search the specified list of directories for a static or shared library file + *lib* and return the full path to that file. If *debug* is true, look for a + debugging version (if that makes sense on the current platform). Return + ``None`` if *lib* wasn't found in any of the specified directories. + + + .. method:: CCompiler.has_function(funcname [, includes=None, include_dirs=None, libraries=None, library_dirs=None]) + + Return a boolean indicating whether *funcname* is supported on the current + platform. The optional arguments can be used to augment the compilation + environment by providing additional include files and paths and libraries and + paths. + + + .. method:: CCompiler.library_dir_option(dir) + + Return the compiler option to add *dir* to the list of directories searched for + libraries. + + + .. method:: CCompiler.library_option(lib) + + Return the compiler option to add *dir* to the list of libraries linked into the + shared library or executable. + + + .. method:: CCompiler.runtime_library_dir_option(dir) + + Return the compiler option to add *dir* to the list of directories searched for + runtime libraries. + + + .. method:: CCompiler.set_executables(**args) + + Define the executables (and options for them) that will be run to perform the + various stages of compilation. The exact set of executables that may be + specified here depends on the compiler class (via the 'executables' class + attribute), but most will have: + + +--------------+------------------------------------------+ + | attribute | description | + +==============+==========================================+ + | *compiler* | the C/C++ compiler | + +--------------+------------------------------------------+ + | *linker_so* | linker used to create shared objects and | + | | libraries | + +--------------+------------------------------------------+ + | *linker_exe* | linker used to create binary executables | + +--------------+------------------------------------------+ + | *archiver* | static library creator | + +--------------+------------------------------------------+ + + On platforms with a command line (Unix, DOS/Windows), each of these is a string + that will be split into executable name and (optional) list of arguments. + (Splitting the string is done similarly to how Unix shells operate: words are + delimited by spaces, but quotes and backslashes can override this. See + :func:`packaging.util.split_quoted`.) + + The following methods invoke stages in the build process. + + + .. method:: CCompiler.compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None]) + + Compile one or more source files. Generates object files (e.g. transforms a + :file:`.c` file to a :file:`.o` file.) + + *sources* must be a list of filenames, most likely C/C++ files, but in reality + anything that can be handled by a particular compiler and compiler class (e.g. + an ``'msvc'`` compiler` can handle resource files in *sources*). Return a list of + object filenames, one per source filename in *sources*. Depending on the + implementation, not all source files will necessarily be compiled, but all + corresponding object filenames will be returned. + + If *output_dir* is given, object files will be put under it, while retaining + their original path component. That is, :file:`foo/bar.c` normally compiles to + :file:`foo/bar.o` (for a Unix implementation); if *output_dir* is *build*, then + it would compile to :file:`build/foo/bar.o`. + + *macros*, if given, must be a list of macro definitions. A macro definition is + either a ``(name, value)`` 2-tuple or a ``(name,)`` 1-tuple. The former defines + a macro; if the value is ``None``, the macro is defined without an explicit + value. The 1-tuple case undefines a macro. Later + definitions/redefinitions/undefinitions take precedence. + + *include_dirs*, if given, must be a list of strings, the directories to add to + the default include file search path for this compilation only. + + *debug* is a boolean; if true, the compiler will be instructed to output debug + symbols in (or alongside) the object file(s). + + *extra_preargs* and *extra_postargs* are implementation-dependent. On platforms + that have the notion of a command line (e.g. Unix, DOS/Windows), they are most + likely lists of strings: extra command-line arguments to prepend/append to the + compiler command line. On other platforms, consult the implementation class + documentation. In any event, they are intended as an escape hatch for those + occasions when the abstract compiler framework doesn't cut the mustard. + + *depends*, if given, is a list of filenames that all targets depend on. If a + source file is older than any file in depends, then the source file will be + recompiled. This supports dependency tracking, but only at a coarse + granularity. + + Raises :exc:`CompileError` on failure. + + + .. method:: CCompiler.create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None]) + + Link a bunch of stuff together to create a static library file. The "bunch of + stuff" consists of the list of object files supplied as *objects*, the extra + object files supplied to :meth:`add_link_object` and/or + :meth:`set_link_objects`, the libraries supplied to :meth:`add_library` and/or + :meth:`set_libraries`, and the libraries supplied as *libraries* (if any). + + *output_libname* should be a library name, not a filename; the filename will be + inferred from the library name. *output_dir* is the directory where the library + file will be put. XXX defaults to what? + + *debug* is a boolean; if true, debugging information will be included in the + library (note that on most platforms, it is the compile step where this matters: + the *debug* flag is included here just for consistency). + + *target_lang* is the target language for which the given objects are being + compiled. This allows specific linkage time treatment of certain languages. + + Raises :exc:`LibError` on failure. + + + .. method:: CCompiler.link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a bunch of stuff together to create an executable or shared library file. + + The "bunch of stuff" consists of the list of object files supplied as *objects*. + *output_filename* should be a filename. If *output_dir* is supplied, + *output_filename* is relative to it (i.e. *output_filename* can provide + directory components if needed). + + *libraries* is a list of libraries to link against. These are library names, + not filenames, since they're translated into filenames in a platform-specific + way (e.g. *foo* becomes :file:`libfoo.a` on Unix and :file:`foo.lib` on + DOS/Windows). However, they can include a directory component, which means the + linker will look in that specific directory rather than searching all the normal + locations. + + *library_dirs*, if supplied, should be a list of directories to search for + libraries that were specified as bare library names (i.e. no directory + component). These are on top of the system default and those supplied to + :meth:`add_library_dir` and/or :meth:`set_library_dirs`. *runtime_library_dirs* + is a list of directories that will be embedded into the shared library and used + to search for other shared libraries that \*it\* depends on at run-time. (This + may only be relevant on Unix.) + + *export_symbols* is a list of symbols that the shared library will export. + (This appears to be relevant only on Windows.) + + *debug* is as for :meth:`compile` and :meth:`create_static_lib`, with the + slight distinction that it actually matters on most platforms (as opposed to + :meth:`create_static_lib`, which includes a *debug* flag mostly for form's + sake). + + *extra_preargs* and *extra_postargs* are as for :meth:`compile` (except of + course that they supply command-line arguments for the particular linker being + used). + + *target_lang* is the target language for which the given objects are being + compiled. This allows specific linkage time treatment of certain languages. + + Raises :exc:`LinkError` on failure. + + + .. method:: CCompiler.link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None]) + + Link an executable. *output_progname* is the name of the file executable, while + *objects* are a list of object filenames to link in. Other arguments are as for + the :meth:`link` method. + + + .. method:: CCompiler.link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a shared library. *output_libname* is the name of the output library, + while *objects* is a list of object filenames to link in. Other arguments are + as for the :meth:`link` method. + + + .. method:: CCompiler.link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a shared object. *output_filename* is the name of the shared object that + will be created, while *objects* is a list of object filenames to link in. + Other arguments are as for the :meth:`link` method. + + + .. method:: CCompiler.preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None]) + + Preprocess a single C/C++ source file, named in *source*. Output will be written + to file named *output_file*, or *stdout* if *output_file* not supplied. + *macros* is a list of macro definitions as for :meth:`compile`, which will + augment the macros set with :meth:`define_macro` and :meth:`undefine_macro`. + *include_dirs* is a list of directory names that will be added to the default + list, in the same way as :meth:`add_include_dir`. + + Raises :exc:`PreprocessError` on failure. + + The following utility methods are defined by the :class:`CCompiler` class, for + use by the various concrete subclasses. + + + .. method:: CCompiler.executable_filename(basename[, strip_dir=0, output_dir='']) + + Returns the filename of the executable for the given *basename*. Typically for + non-Windows platforms this is the same as the basename, while Windows will get + a :file:`.exe` added. + + + .. method:: CCompiler.library_filename(libname[, lib_type='static', strip_dir=0, output_dir='']) + + Returns the filename for the given library name on the current platform. On Unix + a library with *lib_type* of ``'static'`` will typically be of the form + :file:`liblibname.a`, while a *lib_type* of ``'dynamic'`` will be of the form + :file:`liblibname.so`. + + + .. method:: CCompiler.object_filenames(source_filenames[, strip_dir=0, output_dir='']) + + Returns the name of the object files for the given source files. + *source_filenames* should be a list of filenames. + + + .. method:: CCompiler.shared_object_filename(basename[, strip_dir=0, output_dir='']) + + Returns the name of a shared object file for the given file name *basename*. + + + .. method:: CCompiler.execute(func, args[, msg=None, level=1]) + + Invokes :func:`packaging.util.execute` This method invokes a Python function + *func* with the given arguments *args*, after logging and taking into account + the *dry_run* flag. XXX see also. + + + .. method:: CCompiler.spawn(cmd) + + Invokes :func:`packaging.util.spawn`. This invokes an external process to run + the given command. XXX see also. + + + .. method:: CCompiler.mkpath(name[, mode=511]) + + Invokes :func:`packaging.dir_util.mkpath`. This creates a directory and any + missing ancestor directories. XXX see also. + + + .. method:: CCompiler.move_file(src, dst) + + Invokes :meth:`packaging.file_util.move_file`. Renames *src* to *dst*. XXX see + also. + + +:mod:`packaging.compiler.extension` --- The Extension class +=========================================================== + +.. module:: packaging.compiler.extension + :synopsis: Class used to represent C/C++ extension modules. + + +This module provides the :class:`Extension` class, used to represent C/C++ +extension modules. + +.. class:: Extension + + The Extension class describes a single C or C++ extension module. It accepts + the following keyword arguments in its constructor + + +------------------------+--------------------------------+---------------------------+ + | argument name | value | type | + +========================+================================+===========================+ + | *name* | the full name of the | string | + | | extension, including any | | + | | packages --- i.e. *not* a | | + | | filename or pathname, but | | + | | Python dotted name | | + +------------------------+--------------------------------+---------------------------+ + | *sources* | list of source filenames, | string | + | | relative to the distribution | | + | | root (where the setup script | | + | | lives), in Unix form (slash- | | + | | separated) for portability. | | + | | Source files may be C, C++, | | + | | SWIG (.i), platform-specific | | + | | resource files, or whatever | | + | | else is recognized by the | | + | | :command:`build_ext` command | | + | | as source for a Python | | + | | extension. | | + +------------------------+--------------------------------+---------------------------+ + | *include_dirs* | list of directories to search | string | + | | for C/C++ header files (in | | + | | Unix form for portability) | | + +------------------------+--------------------------------+---------------------------+ + | *define_macros* | list of macros to define; each | (string, string) tuple or | + | | macro is defined using a | (name, ``None``) | + | | 2-tuple ``(name, value)``, | | + | | where *value* is | | + | | either the string to define it | | + | | to or ``None`` to define it | | + | | without a particular value | | + | | (equivalent of ``#define FOO`` | | + | | in source or :option:`-DFOO` | | + | | on Unix C compiler command | | + | | line) | | + +------------------------+--------------------------------+---------------------------+ + | *undef_macros* | list of macros to undefine | string | + | | explicitly | | + +------------------------+--------------------------------+---------------------------+ + | *library_dirs* | list of directories to search | string | + | | for C/C++ libraries at link | | + | | time | | + +------------------------+--------------------------------+---------------------------+ + | *libraries* | list of library names (not | string | + | | filenames or paths) to link | | + | | against | | + +------------------------+--------------------------------+---------------------------+ + | *runtime_library_dirs* | list of directories to search | string | + | | for C/C++ libraries at run | | + | | time (for shared extensions, | | + | | this is when the extension is | | + | | loaded) | | + +------------------------+--------------------------------+---------------------------+ + | *extra_objects* | list of extra files to link | string | + | | with (e.g. object files not | | + | | implied by 'sources', static | | + | | library that must be | | + | | explicitly specified, binary | | + | | resource files, etc.) | | + +------------------------+--------------------------------+---------------------------+ + | *extra_compile_args* | any extra platform- and | string | + | | compiler-specific information | | + | | to use when compiling the | | + | | source files in 'sources'. For | | + | | platforms and compilers where | | + | | a command line makes sense, | | + | | this is typically a list of | | + | | command-line arguments, but | | + | | for other platforms it could | | + | | be anything. | | + +------------------------+--------------------------------+---------------------------+ + | *extra_link_args* | any extra platform- and | string | + | | compiler-specific information | | + | | to use when linking object | | + | | files together to create the | | + | | extension (or to create a new | | + | | static Python interpreter). | | + | | Similar interpretation as for | | + | | 'extra_compile_args'. | | + +------------------------+--------------------------------+---------------------------+ + | *export_symbols* | list of symbols to be exported | string | + | | from a shared extension. Not | | + | | used on all platforms, and not | | + | | generally necessary for Python | | + | | extensions, which typically | | + | | export exactly one symbol: | | + | | ``init`` + extension_name. | | + +------------------------+--------------------------------+---------------------------+ + | *depends* | list of files that the | string | + | | extension depends on | | + +------------------------+--------------------------------+---------------------------+ + | *language* | extension language (i.e. | string | + | | ``'c'``, ``'c++'``, | | + | | ``'objc'``). Will be detected | | + | | from the source extensions if | | + | | not provided. | | + +------------------------+--------------------------------+---------------------------+ diff --git a/Doc/library/packaging.database.rst b/Doc/library/packaging.database.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.database.rst @@ -0,0 +1,324 @@ +:mod:`packaging.database` --- Database of installed distributions +================================================================= + +.. module:: packaging.database + :synopsis: Functions to query and manipulate installed distributions. + + +This module provides an implementation of :PEP:`376`. It was originally +intended to land in :mod:`pkgutil`, but with the inclusion of Packaging in the +standard library, it was thought best to include it in a submodule of +:mod:`packaging`, leaving :mod:`pkgutil` to deal with imports. + +Installed Python distributions are represented by instances of +:class:`Distribution`, or :class:`EggInfoDistribution` for legacy egg formats. +Most functions also provide an extra argument ``use_egg_info`` to take legacy +distributions into account. + + +Classes representing installed distributions +-------------------------------------------- + +.. class:: Distribution(path) + + Class representing an installed distribution. It is different from + :class:`packaging.dist.Distribution` which holds the list of files, the + metadata and options during the run of a Packaging command. + + Instantiate with the *path* to a ``.dist-info`` directory. Instances can be + compared and sorted. Other available methods are: + + .. XXX describe how comparison works + + .. method:: get_distinfo_file(path, binary=False) + + Return a read-only file object for a file located at + :file:`{project-version}.dist-info/path}`. *path* should be a + ``'/'``-separated path relative to the ``.dist-info`` directory or an + absolute path; if it is an absolute path and doesn't start with the path + to the :file:`.dist-info` directory, a :class:`PackagingError` is raised. + + If *binary* is ``True``, the file is opened in binary mode. + + .. method:: get_resource_path(relative_path) + + .. TODO + + .. method:: list_distinfo_files(local=False) + + Return an iterator over all files located in the :file:`.dist-info` + directory. If *local* is ``True``, each returned path is transformed into + a local absolute path, otherwise the raw value found in the :file:`RECORD` + file is returned. + + .. method:: list_installed_files(local=False) + + Iterate over the files installed with the distribution and registered in + the :file:`RECORD` file and yield a tuple ``(path, md5, size)`` for each + line. If *local* is ``True``, the returned path is transformed into a + local absolute path, otherwise the raw value is returned. + + A local absolute path is an absolute path in which occurrences of ``'/'`` + have been replaced by :data:`os.sep`. + + .. method:: uses(path) + + Check whether *path* was installed by this distribution (i.e. if the path + is present in the :file:`RECORD` file). *path* can be a local absolute + path or a relative ``'/'``-separated path. Returns a boolean. + + Available attributes: + + .. attribute:: metadata + + Instance of :class:`packaging.metadata.Metadata` filled with the contents + of the :file:`{project-version}.dist-info/METADATA` file. + + .. attribute:: name + + Shortcut for ``metadata['Name']``. + + .. attribute:: version + + Shortcut for ``metadata['Version']``. + + .. attribute:: requested + + Boolean indicating whether this distribution was requested by the user of + automatically installed as a dependency. + + +.. class:: EggInfoDistribution(path) + + Class representing a legacy distribution. It is compatible with distutils' + and setuptools' :file:`.egg-info` and :file:`.egg` files and directories. + + .. FIXME should be named EggDistribution + + Instantiate with the *path* to an egg file or directory. Instances can be + compared and sorted. Other available methods are: + + .. method:: list_installed_files(local=False) + + .. method:: uses(path) + + Available attributes: + + .. attribute:: metadata + + Instance of :class:`packaging.metadata.Metadata` filled with the contents + of the :file:`{project-version}.egg-info/PKG-INFO` or + :file:`{project-version}.egg` file. + + .. attribute:: name + + Shortcut for ``metadata['Name']``. + + .. attribute:: version + + Shortcut for ``metadata['Version']``. + + +Functions to work with the database +----------------------------------- + +.. function:: get_distribution(name, use_egg_info=False, paths=None) + + Return an instance of :class:`Distribution` or :class:`EggInfoDistribution` + for the first installed distribution matching *name*. Egg distributions are + considered only if *use_egg_info* is true; if both a dist-info and an egg + file are found, the dist-info prevails. The directories to be searched are + given in *paths*, which defaults to :data:`sys.path`. Return ``None`` if no + matching distribution is found. + + .. FIXME param should be named use_egg + + +.. function:: get_distributions(use_egg_info=False, paths=None) + + Return an iterator of :class:`Distribution` instances for all installed + distributions found in *paths* (defaults to :data:`sys.path`). If + *use_egg_info* is true, also return instances of :class:`EggInfoDistribution` + for legacy distributions found. + + +.. function:: get_file_users(path) + + Return an iterator over all distributions using *path*, a local absolute path + or a relative ``'/'``-separated path. + + .. XXX does this work with prefixes or full file path only? + + +.. function:: obsoletes_distribution(name, version=None, use_egg_info=False) + + Return an iterator over all distributions that declare they obsolete *name*. + *version* is an optional argument to match only specific releases (see + :mod:`packaging.version`). If *use_egg_info* is true, legacy egg + distributions will be considered as well. + + +.. function:: provides_distribution(name, version=None, use_egg_info=False) + + Return an iterator over all distributions that declare they provide *name*. + *version* is an optional argument to match only specific releases (see + :mod:`packaging.version`). If *use_egg_info* is true, legacy egg + distributions will be considered as well. + + +Utility functions +----------------- + +.. function:: distinfo_dirname(name, version) + + Escape *name* and *version* into a filename-safe form and return the + directory name built from them, for example + :file:`{safename}-{safeversion}.dist-info.` In *name*, runs of + non-alphanumeric characters are replaced with one ``'_'``; in *version*, + spaces become dots, and runs of other non-alphanumeric characters (except + dots) a replaced by one ``'-'``. + + .. XXX wth spaces in version numbers? + +For performance purposes, the list of distributions is being internally +cached. Caching is enabled by default, but you can control it with these +functions: + +.. function:: clear_cache() + + Clear the cache. + +.. function:: disable_cache() + + Disable the cache, without clearing it. + +.. function:: enable_cache() + + Enable the internal cache, without clearing it. + + +Examples +-------- + +Print all information about a distribution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Given a path to a ``.dist-info`` distribution, we shall print out all +information that can be obtained using functions provided in this module:: + + import sys + import packaging.database + + path = input() + # first create the Distribution instance + try: + dist = packaging.database.Distribution(path) + except IOError: + sys.exit('No such distribution') + + print('Information about %r' % dist.name) + print() + + print('Files') + print('=====') + for path, md5, size in dist.list_installed_files(): + print('* Path: %s' % path) + print(' Hash %s, Size: %s bytes' % (md5, size)) + print() + + print('Metadata') + print('========') + for key, value in dist.metadata.items(): + print('%20s: %s' % (key, value)) + print() + + print('Extra') + print('=====') + if dist.requested: + print('* It was installed by user request') + else: + print('* It was installed as a dependency') + +If we save the script above as ``print_info.py``, we can use it to extract +information from a :file:`.dist-info` directory. By typing in the console: + +.. code-block:: sh + + $ echo /tmp/choxie/choxie-2.0.0.9.dist-info | python3 print_info.py + +we get the following output: + +.. code-block:: none + + Information about 'choxie' + + Files + ===== + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py + Hash 5e052db6a478d06bad9ae033e6bc08af, Size: 111 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py + Hash ac56bf496d8d1d26f866235b95f31030, Size: 214 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py + Hash 416aab08dfa846f473129e89a7625bbc, Size: 25 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER + Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA + Hash 696a209967fef3c8b8f5a7bb10386385, Size: 225 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED + Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD + Hash None, Size: None bytes + + Metadata + ======== + Metadata-Version: 1.2 + Name: choxie + Version: 2.0.0.9 + Platform: [] + Supported-Platform: UNKNOWN + Summary: Chocolate with a kick! + Description: UNKNOWN + Keywords: [] + Home-page: UNKNOWN + Author: UNKNOWN + Author-email: UNKNOWN + Maintainer: UNKNOWN + Maintainer-email: UNKNOWN + License: UNKNOWN + Classifier: [] + Download-URL: UNKNOWN + Obsoletes-Dist: ['truffles (<=0.8,>=0.5)', 'truffles (<=0.9,>=0.6)'] + Project-URL: [] + Provides-Dist: ['truffles (1.0)'] + Requires-Dist: ['towel-stuff (0.1)'] + Requires-Python: UNKNOWN + Requires-External: [] + + Extra + ===== + * It was installed as a dependency + + +Find out obsoleted distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now, we take tackle a different problem, we are interested in finding out +which distributions have been obsoleted. This can be easily done as follows:: + + import packaging.database + + # iterate over all distributions in the system + for dist in packaging.database.get_distributions(): + name, version = dist.name, dist.version + # find out which distributions obsolete this name/version combination + replacements = packaging.database.obsoletes_distribution(name, version) + if replacements: + print('%r %s is obsoleted by' % (name, version), + ', '.join(repr(r.name) for r in replacements)) + +This is how the output might look like: + +.. code-block:: none + + 'strawberry' 0.6 is obsoleted by 'choxie' + 'grammar' 1.0a4 is obsoleted by 'towel-stuff' diff --git a/Doc/library/packaging.depgraph.rst b/Doc/library/packaging.depgraph.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.depgraph.rst @@ -0,0 +1,199 @@ +:mod:`packaging.depgraph` --- Dependency graph builder +====================================================== + +.. module:: packaging.depgraph + :synopsis: Graph builder for dependencies between releases. + + +This module provides the means to analyse the dependencies between various +distributions and to create a graph representing these dependency relationships. +In this document, "distribution" refers to an instance of +:class:`packaging.database.Distribution` or +:class:`packaging.database.EggInfoDistribution`. + +.. XXX terminology problem with dist vs. release: dists are installed, but deps + use releases + +.. XXX explain how to use it with dists not installed: Distribution can only be + instantiated with a path, but this module is useful for remote dist too + +.. XXX functions should accept and return iterators, not lists + + +The :class:`DependencyGraph` class +---------------------------------- + +.. class:: DependencyGraph + + Represent a dependency graph between releases. The nodes are distribution + instances; the edge model dependencies. An edge from ``a`` to ``b`` means + that ``a`` depends on ``b``. + + .. method:: add_distribution(distribution) + + Add *distribution* to the graph. + + .. method:: add_edge(x, y, label=None) + + Add an edge from distribution *x* to distribution *y* with the given + *label* (string). + + .. method:: add_missing(distribution, requirement) + + Add a missing *requirement* (string) for the given *distribution*. + + .. method:: repr_node(dist, level=1) + + Print a subgraph starting from *dist*. *level* gives the depth of the + subgraph. + + Direct access to the graph nodes and edges is provided through these + attributes: + + .. attribute:: adjacency_list + + Dictionary mapping distributions to a list of ``(other, label)`` tuples + where ``other`` is a distribution and the edge is labeled with ``label`` + (i.e. the version specifier, if such was provided). + + .. attribute:: reverse_list + + Dictionary mapping distributions to a list of predecessors. This allows + efficient traversal. + + .. attribute:: missing + + Dictionary mapping distributions to a list of requirements that were not + provided by any distribution. + + +Auxiliary functions +------------------- + +.. function:: dependent_dists(dists, dist) + + Recursively generate a list of distributions from *dists* that are dependent + on *dist*. + + .. XXX what does member mean here: "dist is a member of *dists* for which we + are interested" + +.. function:: generate_graph(dists) + + Generate a :class:`DependencyGraph` from the given list of distributions. + + .. XXX make this alternate constructor a DepGraph classmethod or rename; + 'generate' can suggest it creates a file or an image, use 'make' + +.. function:: graph_to_dot(graph, f, skip_disconnected=True) + + Write a DOT output for the graph to the file-like object *f*. + + If *skip_disconnected* is true, all distributions that are not dependent on + any other distribution are skipped. + + .. XXX why is this not a DepGraph method? + + +Example Usage +------------- + +Depict all dependenciess in the system +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First, we shall generate a graph of all the distributions on the system +and then create an image out of it using the tools provided by +`Graphviz `_:: + + from packaging.database import get_distributions + from packaging.depgraph import generate_graph + + dists = list(get_distributions()) + graph = generate_graph(dists) + +It would be interesting to print out the missing requirements. This can be done +as follows:: + + for dist, reqs in graph.missing.items(): + if reqs: + reqs = ' ,'.join(repr(req) for req in reqs) + print('Missing dependencies for %r: %s' % (dist.name, reqs)) + +Example output is: + +.. code-block:: none + + Missing dependencies for 'TurboCheetah': 'Cheetah' + Missing dependencies for 'TurboGears': 'ConfigObj', 'DecoratorTools', 'RuleDispatch' + Missing dependencies for 'jockey': 'PyKDE4.kdecore', 'PyKDE4.kdeui', 'PyQt4.QtCore', 'PyQt4.QtGui' + Missing dependencies for 'TurboKid': 'kid' + Missing dependencies for 'TurboJson: 'DecoratorTools', 'RuleDispatch' + +Now, we proceed with generating a graphical representation of the graph. First +we write it to a file, and then we generate a PNG image using the +:program:`dot` command-line tool:: + + from packaging.depgraph import graph_to_dot + with open('output.dot', 'w') as f: + # only show the interesting distributions, skipping the disconnected ones + graph_to_dot(graph, f, skip_disconnected=True) + +We can create the final picture using: + +.. code-block:: sh + + $ dot -Tpng output.dot > output.png + +An example result is: + +.. figure:: depgraph-output.png + :alt: Example PNG output from packaging.depgraph and dot + +If you want to include egg distributions as well, then the code requires only +one change, namely the line:: + + dists = list(packaging.database.get_distributions()) + +has to be replaced with:: + + dists = list(packaging.database.get_distributions(use_egg_info=True)) + +On many platforms, a richer graph is obtained because at the moment most +distributions are provided in the egg rather than the new standard +``.dist-info`` format. + +.. XXX missing image + + An example of a more involved graph for illustrative reasons can be seen + here: + + .. image:: depgraph_big.png + + +List all dependent distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We will list all distributions that are dependent on some given distibution. +This time, egg distributions will be considered as well:: + + import sys + from packaging.database import get_distribution, get_distributions + from packaging.depgraph import dependent_dists + + dists = list(get_distributions(use_egg_info=True)) + dist = get_distribution('bacon', use_egg_info=True) + if dist is None: + sys.exit('No such distribution in the system') + + deps = dependent_dists(dists, dist) + deps = ', '.join(repr(x.name) for x in deps) + print('Distributions depending on %r: %s' % (dist.name, deps)) + +And this is example output: + +.. with the dependency relationships as in the previous section + (depgraph_big) + +.. code-block:: none + + Distributions depending on 'bacon': 'towel-stuff', 'choxie', 'grammar' diff --git a/Doc/library/packaging.dist.rst b/Doc/library/packaging.dist.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.dist.rst @@ -0,0 +1,102 @@ +:mod:`packaging.dist` --- The Distribution class +================================================ + +.. module:: packaging.dist + :synopsis: Core Distribution class. + + +This module provides the :class:`Distribution` class, which represents the +module distribution being built/packaged/distributed/installed. + +.. class:: Distribution(arguments) + + A :class:`Distribution` describes how to build, package, distribute and + install a Python project. + + The arguments accepted by the constructor are laid out in the following + table. Some of them will end up in a metadata object, the rest will become + data attributes of the :class:`Distribution` instance. + + .. TODO improve constructor to take a Metadata object + named params? + (i.e. Distribution(metadata, cmdclass, py_modules, etc) + .. TODO also remove obsolete(?) script_name, etc. parameters? see what + py2exe and other tools need + + +--------------------+--------------------------------+-------------------------------------------------------------+ + | argument name | value | type | + +====================+================================+=============================================================+ + | *name* | The name of the project | string | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *version* | The version number of the | See :mod:`packaging.version` | + | | release | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *summary* | A single line describing the | a string | + | | project | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *description* | Longer description of the | a string | + | | project | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *author* | The name of the project author | a string | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *author_email* | The email address of the | a string | + | | project author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *maintainer* | The name of the current | a string | + | | maintainer, if different from | | + | | the author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *maintainer_email* | The email address of the | | + | | current maintainer, if | | + | | different from the author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *home_page* | A URL for the proejct | a URL | + | | (homepage) | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *download_url* | A URL to download the project | a URL | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *packages* | A list of Python packages that | a list of strings | + | | packaging will manipulate | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *py_modules* | A list of Python modules that | a list of strings | + | | packaging will manipulate | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *scripts* | A list of standalone scripts | a list of strings | + | | to be built and installed | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *ext_modules* | A list of Python extensions to | A list of instances of | + | | be built | :class:`packaging.compiler.extension.Extension` | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *classifiers* | A list of categories for the | The list of available | + | | distribution | categorizations is at | + | | | http://pypi.python.org/pypi?:action=list_classifiers. | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *distclass* | the :class:`Distribution` | A subclass of | + | | class to use | :class:`packaging.dist.Distribution` | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *script_name* | The name of the setup.py | a string | + | | script - defaults to | | + | | ``sys.argv[0]`` | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *script_args* | Arguments to supply to the | a list of strings | + | | setup script | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *options* | default options for the setup | a string | + | | script | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *license* | The license for the | a string; should be used when there is no suitable License | + | | distribution | classifier, or to specify a classifier | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *keywords* | Descriptive keywords | a list of strings; used by catalogs | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *platforms* | Platforms compatible with this | a list of strings; should be used when there is no | + | | distribution | suitable Platform classifier | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *cmdclass* | A mapping of command names to | a dictionary | + | | :class:`Command` subclasses | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *data_files* | A list of data files to | a list | + | | install | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *package_dir* | A mapping of Python packages | a dictionary | + | | to directory names | | + +--------------------+--------------------------------+-------------------------------------------------------------+ diff --git a/Doc/library/packaging.fancy_getopt.rst b/Doc/library/packaging.fancy_getopt.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.fancy_getopt.rst @@ -0,0 +1,75 @@ +:mod:`packaging.fancy_getopt` --- Wrapper around the getopt module +================================================================== + +.. module:: packaging.fancy_getopt + :synopsis: Additional getopt functionality. + + +.. warning:: + This module is deprecated and will be replaced with :mod:`optparse`. + +This module provides a wrapper around the standard :mod:`getopt` module that +provides the following additional features: + +* short and long options are tied together + +* options have help strings, so :func:`fancy_getopt` could potentially create a + complete usage summary + +* options set attributes of a passed-in object + +* boolean options can have "negative aliases" --- e.g. if :option:`--quiet` is + the "negative alias" of :option:`--verbose`, then :option:`--quiet` on the + command line sets *verbose* to false. + +.. function:: fancy_getopt(options, negative_opt, object, args) + + Wrapper function. *options* is a list of ``(long_option, short_option, + help_string)`` 3-tuples as described in the constructor for + :class:`FancyGetopt`. *negative_opt* should be a dictionary mapping option names + to option names, both the key and value should be in the *options* list. + *object* is an object which will be used to store values (see the :meth:`getopt` + method of the :class:`FancyGetopt` class). *args* is the argument list. Will use + ``sys.argv[1:]`` if you pass ``None`` as *args*. + + +.. class:: FancyGetopt([option_table=None]) + + The option_table is a list of 3-tuples: ``(long_option, short_option, + help_string)`` + + If an option takes an argument, its *long_option* should have ``'='`` appended; + *short_option* should just be a single character, no ``':'`` in any case. + *short_option* should be ``None`` if a *long_option* doesn't have a + corresponding *short_option*. All option tuples must have long options. + +The :class:`FancyGetopt` class provides the following methods: + + +.. method:: FancyGetopt.getopt([args=None, object=None]) + + Parse command-line options in args. Store as attributes on *object*. + + If *args* is ``None`` or not supplied, uses ``sys.argv[1:]``. If *object* is + ``None`` or not supplied, creates a new :class:`OptionDummy` instance, stores + option values there, and returns a tuple ``(args, object)``. If *object* is + supplied, it is modified in place and :func:`getopt` just returns *args*; in + both cases, the returned *args* is a modified copy of the passed-in *args* list, + which is left untouched. + + .. TODO and args returned are? + + +.. method:: FancyGetopt.get_option_order() + + Returns the list of ``(option, value)`` tuples processed by the previous run of + :meth:`getopt` Raises :exc:`RuntimeError` if :meth:`getopt` hasn't been called + yet. + + +.. method:: FancyGetopt.generate_help([header=None]) + + Generate help text (a list of strings, one per suggested line of output) from + the option table for this :class:`FancyGetopt` object. + + If supplied, prints the supplied *header* at the top of the help. diff --git a/Doc/library/packaging.install.rst b/Doc/library/packaging.install.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.install.rst @@ -0,0 +1,112 @@ +:mod:`packaging.install` --- Installation tools +=============================================== + +.. module:: packaging.install + :synopsis: Download and installation building blocks + + +Packaging provides a set of tools to deal with downloads and installation of +distributions. Their role is to download the distribution from indexes, resolve +the dependencies, and provide a safe way to install distributions. An operation +that fails will cleanly roll back, not leave half-installed distributions on the +system. Here's the basic process followed: + +#. Move all distributions that will be removed to a temporary location. + +#. Install all the distributions that will be installed in a temporary location. + +#. If the installation fails, move the saved distributions back to their + location and delete the installed distributions. + +#. Otherwise, move the installed distributions to the right location and delete + the temporary locations. + +This is a higher-level module built on :mod:`packaging.database` and +:mod:`packaging.pypi`. + + +Public functions +---------------- + +.. function:: get_infos(requirements, index=None, installed=None, \ + prefer_final=True) + + Return information about what's going to be installed and upgraded. + *requirements* is a string string containing the requirements for this + project, for example ``'FooBar 1.1'`` or ``'BarBaz (<1.2)'``. + + .. XXX are requirements comma-separated? + + If you want to use another index than the main PyPI, give its URI as *index* + argument. + + *installed* is a list of already installed distributions used to find + satisfied dependencies, obsoleted distributions and eventual conflicts. + + By default, alpha, beta and candidate versions are not picked up. Set + *prefer_final* to false to accept them too. + + The results are returned in a dictionary containing all the information + needed to perform installation of the requirements with the + :func:`install_from_infos` function: + + >>> get_install_info("FooBar (<=1.2)") + {'install': [], 'remove': [], 'conflict': []} + + .. TODO should return tuple or named tuple, not dict + .. TODO use "predicate" or "requirement" consistently in version and here + .. FIXME "info" cannot be plural in English, s/infos/info/ + + +.. function:: install(project) + + +.. function:: install_dists(dists, path, paths=None) + + Safely install all distributions provided in *dists* into *path*. *paths* is + a list of paths where already-installed distributions will be looked for to + find satisfied dependencies and conflicts (default: :data:`sys.path`). + Returns a list of installed dists. + + .. FIXME dists are instances of what? + + +.. function:: install_from_infos(install_path=None, install=[], remove=[], \ + conflicts=[], paths=None) + + Safely install and remove given distributions. This function is designed to + work with the return value of :func:`get_infos`: *install*, *remove* and + *conflicts* should be list of distributions returned by :func:`get_infos`. + If *install* is not empty, *install_path* must be given to specify the path + where the distributions should be installed. *paths* is a list of paths + where already-installed distributions will be looked for (default: + :data:`sys.path`). + + This function is a very basic installer; if *conflicts* is not empty, the + system will be in a conflicting state after the function completes. It is a + building block for more sophisticated installers with conflict resolution + systems. + + .. TODO document typical value for install_path + .. TODO document integration with default schemes, esp. user site-packages + + +.. function:: install_local_project(path) + + Install a distribution from a source directory, which must contain either a + Packaging-compliant :file:`setup.cfg` file or a legacy Distutils + :file:`setup.py` script (in which case Distutils will be used under the hood + to perform the installation). + + +.. function:: remove(project_name, paths=None, auto_confirm=True) + + Remove one distribution from the system. + + .. FIXME this is the only function using "project" instead of dist/release + +.. + Example usage + -------------- + + Get the scheme of what's gonna be installed if we install "foobar": diff --git a/Doc/library/packaging.metadata.rst b/Doc/library/packaging.metadata.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.metadata.rst @@ -0,0 +1,122 @@ +:mod:`packaging.metadata` --- Metadata handling +=============================================== + +.. module:: packaging.metadata + :synopsis: Class holding the metadata of a release. + + +.. TODO use sphinx-autogen to generate basic doc from the docstrings + +.. class:: Metadata + + This class can read and write metadata files complying with any of the + defined versions: 1.0 (:PEP:`241`), 1.1 (:PEP:`314`) and 1.2 (:PEP:`345`). It + implements methods to parse Metadata files and write them, and a mapping + interface to its contents. + + The :PEP:`345` implementation supports the micro-language for the environment + markers, and displays warnings when versions that are supposed to be + :PEP:`386`-compliant are violating the specification. + + +Reading metadata +---------------- + +The :class:`Metadata` class can be instantiated +with the path of the metadata file, and provides a dict-like interface to the +values:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata('PKG-INFO') + >>> metadata.keys()[:5] + ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform') + >>> metadata['Name'] + 'CLVault' + >>> metadata['Version'] + '0.5' + >>> metadata['Requires-Dist'] + ["pywin32; sys.platform == 'win32'", "Sphinx"] + + +The fields that support environment markers can be automatically ignored if +the object is instantiated using the ``platform_dependent`` option. +:class:`Metadata` will interpret in this case +the markers and will automatically remove the fields that are not compliant +with the running environment. Here's an example under Mac OS X. The win32 +dependency we saw earlier is ignored:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata('PKG-INFO', platform_dependent=True) + >>> metadata['Requires-Dist'] + ['Sphinx'] + + +If you want to provide your own execution context, let's say to test the +metadata under a particular environment that is not the current environment, +you can provide your own values in the ``execution_context`` option, which +is the dict that may contain one or more keys of the context the micro-language +expects. + +Here's an example, simulating a win32 environment:: + + >>> from packaging.metadata import Metadata + >>> context = {'sys.platform': 'win32'} + >>> metadata = Metadata('PKG-INFO', platform_dependent=True, + ... execution_context=context) + ... + >>> metadata['Requires-Dist'] = ["pywin32; sys.platform == 'win32'", + ... "Sphinx"] + ... + >>> metadata['Requires-Dist'] + ['pywin32', 'Sphinx'] + + +Writing metadata +---------------- + +Writing metadata can be done using the ``write`` method:: + + >>> metadata.write('/to/my/PKG-INFO') + +The class will pick the best version for the metadata, depending on the values +provided. If all the values provided exist in all versions, the class will +use :attr:`PKG_INFO_PREFERRED_VERSION`. It is set by default to 1.0, the most +widespread version. + + +Conflict checking and best version +---------------------------------- + +Some fields in :PEP:`345` have to comply with the version number specification +defined in :PEP:`386`. When they don't comply, a warning is emitted:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata() + >>> metadata['Requires-Dist'] = ['Funky (Groovie)'] + "Funky (Groovie)" is not a valid predicate + >>> metadata['Requires-Dist'] = ['Funky (1.2)'] + +See also :mod:`packaging.version`. + + +.. TODO talk about check() + + +:mod:`packaging.markers` --- Environment markers +================================================ + +.. module:: packaging.markers + :synopsis: Micro-language for environment markers + + +This is an implementation of environment markers `as defined in PEP 345 +`_. It is used +for some metadata fields. + +.. function:: interpret(marker, execution_context=None) + + Interpret a marker and return a boolean result depending on the environment. + Example: + + >>> interpret("python_version > '1.0'") + True diff --git a/Doc/library/packaging.pypi.dist.rst b/Doc/library/packaging.pypi.dist.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.dist.rst @@ -0,0 +1,114 @@ +:mod:`packaging.pypi.dist` --- Classes representing query results +================================================================= + +.. module:: packaging.pypi.dist + :synopsis: Classes representing the results of queries to indexes. + + +Information coming from the indexes is held in instances of the classes defined +in this module. + +Keep in mind that each project (eg. FooBar) can have several releases +(eg. 1.1, 1.2, 1.3), and each of these releases can be provided in multiple +distributions (eg. a source distribution, a binary one, etc). + + +ReleaseInfo +----------- + +Each release has a project name, version, metadata, and related distributions. + +This information is stored in :class:`ReleaseInfo` +objects. + +.. class:: ReleaseInfo + + +DistInfo +--------- + +:class:`DistInfo` is a simple class that contains +information related to distributions; mainly the URLs where distributions +can be found. + +.. class:: DistInfo + + +ReleasesList +------------ + +The :mod:`~packaging.pypi.dist` module provides a class which works +with lists of :class:`ReleaseInfo` classes; +used to filter and order results. + +.. class:: ReleasesList + + +Example usage +------------- + +Build a list of releases and order them +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assuming we have a list of releases:: + + >>> from packaging.pypi.dist import ReleasesList, ReleaseInfo + >>> fb10 = ReleaseInfo("FooBar", "1.0") + >>> fb11 = ReleaseInfo("FooBar", "1.1") + >>> fb11a = ReleaseInfo("FooBar", "1.1a1") + >>> ReleasesList("FooBar", [fb11, fb11a, fb10]) + >>> releases.sort_releases() + >>> releases.get_versions() + ['1.1', '1.1a1', '1.0'] + >>> releases.add_release("1.2a1") + >>> releases.get_versions() + ['1.1', '1.1a1', '1.0', '1.2a1'] + >>> releases.sort_releases() + ['1.2a1', '1.1', '1.1a1', '1.0'] + >>> releases.sort_releases(prefer_final=True) + >>> releases.get_versions() + ['1.1', '1.0', '1.2a1', '1.1a1'] + + +Add distribution related information to releases +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It's easy to add distribution information to releases:: + + >>> from packaging.pypi.dist import ReleasesList, ReleaseInfo + >>> r = ReleaseInfo("FooBar", "1.0") + >>> r.add_distribution("sdist", url="http://example.org/foobar-1.0.tar.gz") + >>> r.dists + {'sdist': FooBar 1.0 sdist} + >>> r['sdist'].url + {'url': 'http://example.org/foobar-1.0.tar.gz', 'hashname': None, 'hashval': + None, 'is_external': True} + + +Getting attributes from the dist objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To abstract querying information returned from the indexes, attributes and +release information can be retrieved directly from dist objects. + +For instance, if you have a release instance that does not contain the metadata +attribute, it can be fetched by using the "fetch_metadata" method:: + + >>> r = Release("FooBar", "1.1") + >>> print r.metadata + None # metadata field is actually set to "None" + >>> r.fetch_metadata() + + +.. XXX add proper roles to these constructs + + +It's possible to retrieve a project's releases (`fetch_releases`), +metadata (`fetch_metadata`) and distributions (`fetch_distributions`) using +a similar work flow. + +.. XXX what is possible? + +Internally, this is possible because while retrieving information about +projects, releases or distributions, a reference to the client used is +stored which can be accessed using the objects `_index` attribute. diff --git a/Doc/library/packaging.pypi.rst b/Doc/library/packaging.pypi.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.rst @@ -0,0 +1,53 @@ +:mod:`packaging.pypi` --- Interface to projects indexes +======================================================= + +.. module:: packaging.pypi + :synopsis: Low-level and high-level APIs to query projects indexes. + + +Packaging queries PyPI to get information about projects or download them. The +low-level facilities used internally are also part of the public API designed to +be used by other tools. + +The :mod:`packaging.pypi` package provides those facilities, which can be +used to access information about Python projects registered at indexes, the +main one being PyPI, located ad http://pypi.python.org/. + +There is two ways to retrieve data from these indexes: a screen-scraping +interface called the "simple API", and XML-RPC. The first one uses HTML pages +located under http://pypi.python.org/simple/, the second one makes XML-RPC +requests to http://pypi.python.org/pypi/. All functions and classes also work +with other indexes such as mirrors, which typically implement only the simple +interface. + +Packaging provides a class that wraps both APIs to provide full query and +download functionality: :class:`packaging.pypi.client.ClientWrapper`. If you +want more control, you can use the underlying classes +:class:`packaging.pypi.simple.Crawler` and :class:`packaging.pypi.xmlrpc.Client` +to connect to one specific interface. + + +:mod:`packaging.pypi.client` --- High-level query API +===================================================== + +.. module:: packaging.pypi.client + :synopsis: Wrapper around :mod;`packaging.pypi.xmlrpc` and + :mod:`packaging.pypi.simple` to query indexes. + + +This module provides a high-level API to query indexes and search +for releases and distributions. The aim of this module is to choose the best +way to query the API automatically, either using XML-RPC or the simple index, +with a preference toward the latter. + +.. class:: ClientWrapper + + Instances of this class will use the simple interface or XML-RPC requests to + query indexes and return :class:`packaging.pypi.dist.ReleaseInfo` and + :class:`packaging.pypi.dist.ReleasesList` objects. + + .. method:: find_projects + + .. method:: get_release + + .. method:: get_releases diff --git a/Doc/library/packaging.pypi.simple.rst b/Doc/library/packaging.pypi.simple.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.simple.rst @@ -0,0 +1,157 @@ +:mod:`packaging.pypi.simple` --- Crawler using the PyPI "simple" interface +========================================================================== + +.. module:: packaging.pypi.simple + :synopsis: Crawler using the screen-scraping "simple" interface to fetch info + and distributions. + + +`packaging.pypi.simple` can process Python Package Indexes and provides +useful information about distributions. It also can crawl local indexes, for +instance. + +You should use `packaging.pypi.simple` for: + + * Search distributions by name and versions. + * Process index external pages. + * Download distributions by name and versions. + +And should not be used for: + + * Things that will end up in too long index processing (like "finding all + distributions with a specific version, no matters the name") + + +API +--- + +.. class:: Crawler + + +Usage Exemples +--------------- + +To help you understand how using the `Crawler` class, here are some basic +usages. + +Request the simple index to get a specific distribution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Supposing you want to scan an index to get a list of distributions for +the "foobar" project. You can use the "get_releases" method for that. +The get_releases method will browse the project page, and return +:class:`ReleaseInfo` objects for each found link that rely on downloads. :: + + >>> from packaging.pypi.simple import Crawler + >>> crawler = Crawler() + >>> crawler.get_releases("FooBar") + [, ] + + +Note that you also can request the client about specific versions, using version +specifiers (described in `PEP 345 +`_):: + + >>> client.get_releases("FooBar < 1.2") + [, ] + + +`get_releases` returns a list of :class:`ReleaseInfo`, but you also can get the +best distribution that fullfil your requirements, using "get_release":: + + >>> client.get_release("FooBar < 1.2") + + + +Download distributions +^^^^^^^^^^^^^^^^^^^^^^ + +As it can get the urls of distributions provided by PyPI, the `Crawler` +client also can download the distributions and put it for you in a temporary +destination:: + + >>> client.download("foobar") + /tmp/temp_dir/foobar-1.2.tar.gz + + +You also can specify the directory you want to download to:: + + >>> client.download("foobar", "/path/to/my/dir") + /path/to/my/dir/foobar-1.2.tar.gz + + +While downloading, the md5 of the archive will be checked, if not matches, it +will try another time, then if fails again, raise `MD5HashDoesNotMatchError`. + +Internally, that's not the Crawler which download the distributions, but the +`DistributionInfo` class. Please refer to this documentation for more details. + + +Following PyPI external links +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default behavior for packaging is to *not* follow the links provided +by HTML pages in the "simple index", to find distributions related +downloads. + +It's possible to tell the PyPIClient to follow external links by setting the +`follow_externals` attribute, on instantiation or after:: + + >>> client = Crawler(follow_externals=True) + +or :: + + >>> client = Crawler() + >>> client.follow_externals = True + + +Working with external indexes, and mirrors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default `Crawler` behavior is to rely on the Python Package index stored +on PyPI (http://pypi.python.org/simple). + +As you can need to work with a local index, or private indexes, you can specify +it using the index_url parameter:: + + >>> client = Crawler(index_url="file://filesystem/path/") + +or :: + + >>> client = Crawler(index_url="http://some.specific.url/") + + +You also can specify mirrors to fallback on in case the first index_url you +provided doesnt respond, or not correctly. The default behavior for +`Crawler` is to use the list provided by Python.org DNS records, as +described in the :PEP:`381` about mirroring infrastructure. + +If you don't want to rely on these, you could specify the list of mirrors you +want to try by specifying the `mirrors` attribute. It's a simple iterable:: + + >>> mirrors = ["http://first.mirror","http://second.mirror"] + >>> client = Crawler(mirrors=mirrors) + + +Searching in the simple index +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It's possible to search for projects with specific names in the package index. +Assuming you want to find all projects containing the "distutils" keyword:: + + >>> c.search_projects("distutils") + [, , , , , , ] + + +You can also search the projects starting with a specific text, or ending with +that text, using a wildcard:: + + >>> c.search_projects("distutils*") + [, , ] + + >>> c.search_projects("*distutils") + [, , , , ] diff --git a/Doc/library/packaging.pypi.xmlrpc.rst b/Doc/library/packaging.pypi.xmlrpc.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.xmlrpc.rst @@ -0,0 +1,143 @@ +:mod:`packaging.pypi.xmlrpc` --- Crawler using the PyPI XML-RPC interface +========================================================================= + +.. module:: packaging.pypi.xmlrpc + :synopsis: Client using XML-RPC requests to fetch info and distributions. + + +Indexes can be queried using XML-RPC calls, and Packaging provides a simple +way to interface with XML-RPC. + +You should **use** XML-RPC when: + +* Searching the index for projects **on other fields than project + names**. For instance, you can search for projects based on the + author_email field. +* Searching all the versions that have existed for a project. +* you want to retrieve METADATAs information from releases or + distributions. + + +You should **avoid using** XML-RPC method calls when: + +* Retrieving the last version of a project +* Getting the projects with a specific name and version. +* The simple index can match your needs + + +When dealing with indexes, keep in mind that the index queries will always +return you :class:`packaging.pypi.dist.ReleaseInfo` and +:class:`packaging.pypi.dist.ReleasesList` objects. + +Some methods here share common APIs with the one you can find on +:class:`packaging.pypi.simple`, internally, :class:`packaging.pypi.client` +is inherited by :class:`Client` + + +API +--- + +.. class:: Client + + +Usage examples +-------------- + +Use case described here are use case that are not common to the other clients. +If you want to see all the methods, please refer to API or to usage examples +described in :class:`packaging.pypi.client.Client` + + +Finding releases +^^^^^^^^^^^^^^^^ + +It's a common use case to search for "things" within the index. We can +basically search for projects by their name, which is the most used way for +users (eg. "give me the last version of the FooBar project"). + +This can be accomplished using the following syntax:: + + >>> client = xmlrpc.Client() + >>> client.get_release("Foobar (<= 1.3)) + + >>> client.get_releases("FooBar (<= 1.3)") + [FooBar 1.1, FooBar 1.1.1, FooBar 1.2, FooBar 1.2.1] + + +And we also can find for specific fields:: + + >>> client.search_projects(field=value) + + +You could specify the operator to use, default is "or":: + + >>> client.search_projects(field=value, operator="and") + + +The specific fields you can search are: + +* name +* version +* author +* author_email +* maintainer +* maintainer_email +* home_page +* license +* summary +* description +* keywords +* platform +* download_url + + +Getting metadata information +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +XML-RPC is a prefered way to retrieve metadata information from indexes. +It's really simple to do so:: + + >>> client = xmlrpc.Client() + >>> client.get_metadata("FooBar", "1.1") + + + +Assuming we already have a :class:`packaging.pypi.ReleaseInfo` object defined, +it's possible to pass it to the xmlrpc client to retrieve and complete its +metadata:: + + >>> foobar11 = ReleaseInfo("FooBar", "1.1") + >>> client = xmlrpc.Client() + >>> returned_release = client.get_metadata(release=foobar11) + >>> returned_release + + + +Get all the releases of a project +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To retrieve all the releases for a project, you can build them using +`get_releases`:: + + >>> client = xmlrpc.Client() + >>> client.get_releases("FooBar") + [, , ] + + +Get information about distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Indexes have information about projects, releases **and** distributions. +If you're not familiar with those, please refer to the documentation of +:mod:`packaging.pypi.dist`. + +It's possible to retrieve information about distributions, e.g "what are the +existing distributions for this release ? How to retrieve them ?":: + + >>> client = xmlrpc.Client() + >>> release = client.get_distributions("FooBar", "1.1") + >>> release.dists + {'sdist': , 'bdist': } + +As you see, this does not return a list of distributions, but a release, +because a release can be used like a list of distributions. diff --git a/Doc/library/packaging.rst b/Doc/library/packaging.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.rst @@ -0,0 +1,78 @@ +:mod:`packaging` --- Packaging support +====================================== + +.. module:: packaging + :synopsis: Packaging system and building blocks for other packaging systems. +.. sectionauthor:: Fred L. Drake, Jr. , distutils and packaging + contributors + + +The :mod:`packaging` package provides support for building, packaging, +distributing and installing additional projects into a Python installation. +Projects may include Python modules, extension modules, packages and scripts. +:mod:`packaging` also provides building blocks for other packaging systems +that are not tied to the command system. + +This manual is the reference documentation for those standalone building +blocks and for extending Packaging. If you're looking for the user-centric +guides to install a project or package your own code, head to `See also`__. + + +Building blocks +--------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging-misc + packaging.version + packaging.metadata + packaging.database + packaging.depgraph + packaging.pypi + packaging.pypi.dist + packaging.pypi.simple + packaging.pypi.xmlrpc + packaging.install + + +The command machinery +--------------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging.dist + packaging.command + packaging.compiler + packaging.fancy_getopt + + +Other utilities +---------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging.util + packaging.tests.pypi_server + +.. XXX missing: compat config create (dir_util) run pypi.{base,mirrors} + + +.. __: + +.. seealso:: + + :ref:`packaging-index` + The manual for developers of Python projects who want to package and + distribute them. This describes how to use :mod:`packaging` to make + projects easily found and added to an existing Python installation. + + :ref:`packaging-install-index` + A user-centered manual which includes information on adding projects + into an existing Python installation. You do not need to be a Python + programmer to read this manual. diff --git a/Doc/library/packaging.tests.pypi_server.rst b/Doc/library/packaging.tests.pypi_server.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.tests.pypi_server.rst @@ -0,0 +1,105 @@ +:mod:`packaging.tests.pypi_server` --- PyPI mock server +======================================================= + +.. module:: packaging.tests.pypi_server + :synopsis: Mock server used to test PyPI-related modules and commands. + + +When you are testing code that works with Packaging, you might find these tools +useful. + + +The mock server +--------------- + +.. class:: PyPIServer + + PyPIServer is a class that implements an HTTP server running in a separate + thread. All it does is record the requests for further inspection. The recorded + data is available under ``requests`` attribute. The default + HTTP response can be overridden with the ``default_response_status``, + ``default_response_headers`` and ``default_response_data`` attributes. + + By default, when accessing the server with urls beginning with `/simple/`, + the server also record your requests, but will look for files under + the `/tests/pypiserver/simple/` path. + + You can tell the sever to serve static files for other paths. This could be + accomplished by using the `static_uri_paths` parameter, as below:: + + server = PyPIServer(static_uri_paths=["first_path", "second_path"]) + + + You need to create the content that will be served under the + `/tests/pypiserver/default` path. If you want to serve content from another + place, you also can specify another filesystem path (which needs to be under + `tests/pypiserver/`. This will replace the default behavior of the server, and + it will not serve content from the `default` dir :: + + server = PyPIServer(static_filesystem_paths=["path/to/your/dir"]) + + + If you just need to add some paths to the existing ones, you can do as shown, + keeping in mind that the server will always try to load paths in reverse order + (e.g here, try "another/super/path" then the default one) :: + + server = PyPIServer(test_static_path="another/super/path") + server = PyPIServer("another/super/path") + # or + server.static_filesystem_paths.append("another/super/path") + + + As a result of what, in your tests, while you need to use the PyPIServer, in + order to isolates the test cases, the best practice is to place the common files + in the `default` folder, and to create a directory for each specific test case:: + + server = PyPIServer(static_filesystem_paths = ["default", "test_pypi_server"], + static_uri_paths=["simple", "external"]) + + +Base class and decorator for tests +---------------------------------- + +.. class:: PyPIServerTestCase + + ``PyPIServerTestCase`` is a test case class with setUp and tearDown methods that + take care of a single PyPIServer instance attached as a ``pypi`` attribute on + the test class. Use it as one of the base classes in your test case:: + + + class UploadTestCase(PyPIServerTestCase): + + def test_something(self): + cmd = self.prepare_command() + cmd.ensure_finalized() + cmd.repository = self.pypi.full_address + cmd.run() + + environ, request_data = self.pypi.requests[-1] + self.assertEqual(request_data, EXPECTED_REQUEST_DATA) + + +.. decorator:: use_pypi_server + + You also can use a decorator for your tests, if you do not need the same server + instance along all you test case. So, you can specify, for each test method, + some initialisation parameters for the server. + + For this, you need to add a `server` parameter to your method, like this:: + + class SampleTestCase(TestCase): + + @use_pypi_server() + def test_something(self, server): + ... + + + The decorator will instantiate the server for you, and run and stop it just + before and after your method call. You also can pass the server initializer, + just like this:: + + class SampleTestCase(TestCase): + + @use_pypi_server("test_case_name") + def test_something(self, server): + ... diff --git a/Doc/library/packaging.util.rst b/Doc/library/packaging.util.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.util.rst @@ -0,0 +1,186 @@ +:mod:`packaging.util` --- Miscellaneous utility functions +========================================================= + +.. module:: packaging.util + :synopsis: Miscellaneous utility functions. + + +This module contains various helpers for the other modules. + +.. XXX a number of functions are missing, but the module may be split first + (it's ginormous right now, some things could go to compat for example) + +.. function:: get_platform() + + Return a string that identifies the current platform. This is used mainly to + distinguish platform-specific build directories and platform-specific built + distributions. Typically includes the OS name and version and the + architecture (as supplied by 'os.uname()'), although the exact information + included depends on the OS; e.g. for IRIX the architecture isn't particularly + important (IRIX only runs on SGI hardware), but for Linux the kernel version + isn't particularly important. + + Examples of returned values: + + * ``linux-i586`` + * ``linux-alpha`` + * ``solaris-2.6-sun4u`` + * ``irix-5.3`` + * ``irix64-6.2`` + + For non-POSIX platforms, currently just returns ``sys.platform``. + + For Mac OS X systems the OS version reflects the minimal version on which + binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` + during the build of Python), not the OS version of the current system. + + For universal binary builds on Mac OS X the architecture value reflects + the univeral binary status instead of the architecture of the current + processor. For 32-bit universal binaries the architecture is ``fat``, + for 64-bit universal binaries the architecture is ``fat64``, and + for 4-way universal binaries the architecture is ``universal``. Starting + from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for + a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for + a univeral build with the i386 and x86_64 architectures + + Examples of returned values on Mac OS X: + + * ``macosx-10.3-ppc`` + + * ``macosx-10.3-fat`` + + * ``macosx-10.5-universal`` + + * ``macosx-10.6-intel`` + + .. XXX reinvention of platform module? + + +.. function:: convert_path(pathname) + + Return 'pathname' as a name that will work on the native filesystem, i.e. + split it on '/' and put it back together again using the current directory + separator. Needed because filenames in the setup script are always supplied + in Unix style, and have to be converted to the local convention before we + can actually use them in the filesystem. Raises :exc:`ValueError` on + non-Unix-ish systems if *pathname* either starts or ends with a slash. + + +.. function:: change_root(new_root, pathname) + + Return *pathname* with *new_root* prepended. If *pathname* is relative, this + is equivalent to ``os.path.join(new_root,pathname)`` Otherwise, it requires + making *pathname* relative and then joining the two, which is tricky on + DOS/Windows. + + +.. function:: check_environ() + + Ensure that 'os.environ' has all the environment variables we guarantee that + users can use in config files, command-line options, etc. Currently this + includes: + + * :envvar:`HOME` - user's home directory (Unix only) + * :envvar:`PLAT` - description of the current platform, including hardware + and OS (see :func:`get_platform`) + + +.. function:: find_executable(executable, path=None) + + Search the path for a given executable name. + + +.. function:: subst_vars(s, local_vars) + + Perform shell/Perl-style variable substitution on *s*. Every occurrence of + ``$`` followed by a name is considered a variable, and variable is + substituted by the value found in the *local_vars* dictionary, or in + ``os.environ`` if it's not in *local_vars*. *os.environ* is first + checked/augmented to guarantee that it contains certain values: see + :func:`check_environ`. Raise :exc:`ValueError` for any variables not found + in either *local_vars* or ``os.environ``. + + Note that this is not a fully-fledged string interpolation function. A valid + ``$variable`` can consist only of upper and lower case letters, numbers and + an underscore. No { } or ( ) style quoting is available. + + +.. function:: split_quoted(s) + + Split a string up according to Unix shell-like rules for quotes and + backslashes. In short: words are delimited by spaces, as long as those spaces + are not escaped by a backslash, or inside a quoted string. Single and double + quotes are equivalent, and the quote characters can be backslash-escaped. + The backslash is stripped from any two-character escape sequence, leaving + only the escaped character. The quote characters are stripped from any + quoted string. Returns a list of words. + + .. TODO Should probably be moved into the standard library. + + +.. function:: execute(func, args[, msg=None, verbose=0, dry_run=0]) + + Perform some action that affects the outside world (for instance, writing to + the filesystem). Such actions are special because they are disabled by the + *dry_run* flag. This method takes care of all that bureaucracy for you; + all you have to do is supply the function to call and an argument tuple for + it (to embody the "external action" being performed), and an optional message + to print. + + +.. function:: newer(source, target) + + Return true if *source* exists and is more recently modified than *target*, + or if *source* exists and *target* doesn't. Return false if both exist and + *target* is the same age or newer than *source*. Raise + :exc:`PackagingFileError` if *source* does not exist. + + +.. function:: strtobool(val) + + Convert a string representation of truth to true (1) or false (0). + + True values are ``y``, ``yes``, ``t``, ``true``, ``on`` and ``1``; false + values are ``n``, ``no``, ``f``, ``false``, ``off`` and ``0``. Raises + :exc:`ValueError` if *val* is anything else. + +.. TODO Add :term: markup to bytecode when merging into the stdlib + +.. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None]) + + Byte-compile a collection of Python source files to either :file:`.pyc` or + :file:`.pyo` files in the same directory. *py_files* is a list of files to + compile; any files that don't end in :file:`.py` are silently skipped. + *optimize* must be one of the following: + + * ``0`` - don't optimize (generate :file:`.pyc`) + * ``1`` - normal optimization (like ``python -O``) + * ``2`` - extra optimization (like ``python -OO``) + + If *force* is true, all files are recompiled regardless of timestamps. + + The source filename encoded in each bytecode file defaults to the filenames + listed in *py_files*; you can modify these with *prefix* and *basedir*. + *prefix* is a string that will be stripped off of each source filename, and + *base_dir* is a directory name that will be prepended (after *prefix* is + stripped). You can supply either or both (or neither) of *prefix* and + *base_dir*, as you wish. + + If *dry_run* is true, doesn't actually do anything that would affect the + filesystem. + + Byte-compilation is either done directly in this interpreter process with the + standard :mod:`py_compile` module, or indirectly by writing a temporary + script and executing it. Normally, you should let :func:`byte_compile` + figure out to use direct compilation or not (see the source for details). + The *direct* flag is used by the script generated in indirect mode; unless + you know what you're doing, leave it set to ``None``. + + +.. function:: rfc822_escape(header) + + Return a version of *header* escaped for inclusion in an :rfc:`822` header, by + ensuring there are 8 spaces space after each newline. Note that it does no + other modification of the string. + + .. TODO this _can_ be replaced diff --git a/Doc/library/packaging.version.rst b/Doc/library/packaging.version.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.version.rst @@ -0,0 +1,104 @@ +:mod:`packaging.version` --- Version number classes +=================================================== + +.. module:: packaging.version + :synopsis: Classes that represent project version numbers. + + +This module contains classes and functions useful to deal with version numbers. +It's an implementation of version specifiers `as defined in PEP 345 +`_. + + +Version numbers +--------------- + +.. class:: NormalizedVersion(self, s, error_on_huge_major_num=True) + + A specific version of a distribution, as described in PEP 345. *s* is a + string object containing the version number (for example ``'1.2b1'``), + *error_on_huge_major_num* a boolean specifying whether to consider an + apparent use of a year or full date as the major version number an error. + + The rationale for the second argument is that there were projects using years + or full dates as version numbers, which could cause problems with some + packaging systems sorting. + + Instances of this class can be compared and sorted:: + + >>> NormalizedVersion('1.2b1') < NormalizedVersion('1.2') + True + + :class:`NormalizedVersion` is used internally by :class:`VersionPredicate` to + do its work. + + +.. class:: IrrationalVersionError + + Exception raised when an invalid string is given to + :class:`NormalizedVersion`. + + >>> NormalizedVersion("irrational_version_number") + ... + IrrationalVersionError: irrational_version_number + + +.. function:: suggest_normalized_version(s) + + Before standardization in PEP 386, various schemes were in use. Packaging + provides a function to try to convert any string to a valid, normalized + version:: + + >>> suggest_normalized_version('2.1-rc1') + 2.1c1 + + + If :func:`suggest_normalized_version` can't make sense of the given string, + it will return ``None``:: + + >>> print(suggest_normalized_version('not a version')) + None + + +Version predicates +------------------ + +.. class:: VersionPredicate(predicate) + + This class deals with the parsing of field values like + ``ProjectName (>=version)``. + + .. method:: match(version) + + Test if a version number matches the predicate: + + >>> version = VersionPredicate("ProjectName (<1.2, >1.0)") + >>> version.match("1.2.1") + False + >>> version.match("1.1.1") + True + + +Validation helpers +------------------ + +If you want to use :term:`LBYL`-style checks instead of instantiating the +classes and catching :class:`IrrationalVersionError` and :class:`ValueError`, +you can use these functions: + +.. function:: is_valid_version(predicate) + + Check whether the given string is a valid version number. Example of valid + strings: ``'1.2'``, ``'4.2.0.dev4'``, ``'2.5.4.post2'``. + + +.. function:: is_valid_versions(predicate) + + Check whether the given string is a valid value for specifying multiple + versions, such as in the Requires-Python field. Example: ``'2.7, >=3.2'``. + + +.. function:: is_valid_predicate(predicate) + + Check whether the given string is a valid version predicate. Examples: + ``'some.project == 4.5, <= 4.7'``, ``'speciallib (> 1.0, != 1.4.2, < 2.0)'``. diff --git a/Doc/library/python.rst b/Doc/library/python.rst --- a/Doc/library/python.rst +++ b/Doc/library/python.rst @@ -25,4 +25,5 @@ inspect.rst site.rst fpectl.rst + packaging.rst distutils.rst diff --git a/Doc/packaging/builtdist.rst b/Doc/packaging/builtdist.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/builtdist.rst @@ -0,0 +1,307 @@ +.. _packaging-built-dist: + +**************************** +Creating Built Distributions +**************************** + +A "built distribution" is what you're probably used to thinking of either as a +"binary package" or an "installer" (depending on your background). It's not +necessarily binary, though, because it might contain only Python source code +and/or byte-code; and we don't call it a package, because that word is already +spoken for in Python. (And "installer" is a term specific to the world of +mainstream desktop systems.) + +A built distribution is how you make life as easy as possible for installers of +your module distribution: for users of RPM-based Linux systems, it's a binary +RPM; for Windows users, it's an executable installer; for Debian-based Linux +users, it's a Debian package; and so forth. Obviously, no one person will be +able to create built distributions for every platform under the sun, so the +Distutils are designed to enable module developers to concentrate on their +specialty---writing code and creating source distributions---while an +intermediary species called *packagers* springs up to turn source distributions +into built distributions for as many platforms as there are packagers. + +Of course, the module developer could be his own packager; or the packager could +be a volunteer "out there" somewhere who has access to a platform which the +original developer does not; or it could be software periodically grabbing new +source distributions and turning them into built distributions for as many +platforms as the software has access to. Regardless of who they are, a packager +uses the setup script and the :command:`bdist` command family to generate built +distributions. + +As a simple example, if I run the following command in the Distutils source +tree:: + + python setup.py bdist + +then the Distutils builds my module distribution (the Distutils itself in this +case), does a "fake" installation (also in the :file:`build` directory), and +creates the default type of built distribution for my platform. The default +format for built distributions is a "dumb" tar file on Unix, and a simple +executable installer on Windows. (That tar file is considered "dumb" because it +has to be unpacked in a specific location to work.) + +Thus, the above command on a Unix system creates +:file:`Distutils-1.0.{plat}.tar.gz`; unpacking this tarball from the right place +installs the Distutils just as though you had downloaded the source distribution +and run ``python setup.py install``. (The "right place" is either the root of +the filesystem or Python's :file:`{prefix}` directory, depending on the options +given to the :command:`bdist_dumb` command; the default is to make dumb +distributions relative to :file:`{prefix}`.) + +Obviously, for pure Python distributions, this isn't any simpler than just +running ``python setup.py install``\ ---but for non-pure distributions, which +include extensions that would need to be compiled, it can mean the difference +between someone being able to use your extensions or not. And creating "smart" +built distributions, such as an executable installer for +Windows, is far more convenient for users even if your distribution doesn't +include any extensions. + +The :command:`bdist` command has a :option:`--formats` option, similar to the +:command:`sdist` command, which you can use to select the types of built +distribution to generate: for example, :: + + python setup.py bdist --format=zip + +would, when run on a Unix system, create :file:`Distutils-1.0.{plat}.zip`\ +---again, this archive would be unpacked from the root directory to install the +Distutils. + +The available formats for built distributions are: + ++-------------+------------------------------+---------+ +| Format | Description | Notes | ++=============+==============================+=========+ +| ``gztar`` | gzipped tar file | (1),(3) | +| | (:file:`.tar.gz`) | | ++-------------+------------------------------+---------+ +| ``ztar`` | compressed tar file | \(3) | +| | (:file:`.tar.Z`) | | ++-------------+------------------------------+---------+ +| ``tar`` | tar file (:file:`.tar`) | \(3) | ++-------------+------------------------------+---------+ +| ``zip`` | zip file (:file:`.zip`) | (2),(4) | ++-------------+------------------------------+---------+ +| ``wininst`` | self-extracting ZIP file for | \(4) | +| | Windows | | ++-------------+------------------------------+---------+ +| ``msi`` | Microsoft Installer. | | ++-------------+------------------------------+---------+ + + +Notes: + +(1) + default on Unix + +(2) + default on Windows + +(3) + requires external utilities: :program:`tar` and possibly one of :program:`gzip`, + :program:`bzip2`, or :program:`compress` + +(4) + requires either external :program:`zip` utility or :mod:`zipfile` module (part + of the standard Python library since Python 1.6) + +You don't have to use the :command:`bdist` command with the :option:`--formats` +option; you can also use the command that directly implements the format you're +interested in. Some of these :command:`bdist` "sub-commands" actually generate +several similar formats; for instance, the :command:`bdist_dumb` command +generates all the "dumb" archive formats (``tar``, ``ztar``, ``gztar``, and +``zip``). The :command:`bdist` sub-commands, and the formats generated by +each, are: + ++--------------------------+-----------------------+ +| Command | Formats | ++==========================+=======================+ +| :command:`bdist_dumb` | tar, ztar, gztar, zip | ++--------------------------+-----------------------+ +| :command:`bdist_wininst` | wininst | ++--------------------------+-----------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-----------------------+ + +The following sections give details on the individual :command:`bdist_\*` +commands. + + +.. _packaging-creating-dumb: + +Creating dumb built distributions +================================= + +.. XXX Need to document absolute vs. prefix-relative packages here, but first + I have to implement it! + + +.. _packaging-creating-wininst: + +Creating Windows Installers +=========================== + +Executable installers are the natural format for binary distributions on +Windows. They display a nice graphical user interface, display some information +about the module distribution to be installed taken from the metadata in the +setup script, let the user select a few options, and start or cancel the +installation. + +Since the metadata is taken from the setup script, creating Windows installers +is usually as easy as running:: + + python setup.py bdist_wininst + +or the :command:`bdist` command with the :option:`--formats` option:: + + python setup.py bdist --formats=wininst + +If you have a pure module distribution (only containing pure Python modules and +packages), the resulting installer will be version independent and have a name +like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix +platforms or Mac OS X. + +If you have a non-pure distribution, the extensions can only be created on a +Windows platform, and will be Python version dependent. The installer filename +will reflect this and now has the form :file:`foo-1.0.win32-py2.0.exe`. You +have to create a separate installer for every Python version you want to +support. + +.. TODO Add :term: markup to bytecode when merging into the stdlib + +The installer will try to compile pure modules into bytecode after installation +on the target system in normal and optimizing mode. If you don't want this to +happen for some reason, you can run the :command:`bdist_wininst` command with +the :option:`--no-target-compile` and/or the :option:`--no-target-optimize` +option. + +By default the installer will display the cool "Python Powered" logo when it is +run, but you can also supply your own 152x261 bitmap which must be a Windows +:file:`.bmp` file with the :option:`--bitmap` option. + +The installer will also display a large title on the desktop background window +when it is run, which is constructed from the name of your distribution and the +version number. This can be changed to another text by using the +:option:`--title` option. + +The installer file will be written to the "distribution directory" --- normally +:file:`dist/`, but customizable with the :option:`--dist-dir` option. + +.. _packaging-cross-compile-windows: + +Cross-compiling on Windows +========================== + +Starting with Python 2.6, packaging is capable of cross-compiling between +Windows platforms. In practice, this means that with the correct tools +installed, you can use a 32bit version of Windows to create 64bit extensions +and vice-versa. + +To build for an alternate platform, specify the :option:`--plat-name` option +to the build command. Valid values are currently 'win32', 'win-amd64' and +'win-ia64'. For example, on a 32bit version of Windows, you could execute:: + + python setup.py build --plat-name=win-amd64 + +to build a 64bit version of your extension. The Windows Installers also +support this option, so the command:: + + python setup.py build --plat-name=win-amd64 bdist_wininst + +would create a 64bit installation executable on your 32bit version of Windows. + +To cross-compile, you must download the Python source code and cross-compile +Python itself for the platform you are targetting - it is not possible from a +binary installtion of Python (as the .lib etc file for other platforms are +not included.) In practice, this means the user of a 32 bit operating +system will need to use Visual Studio 2008 to open the +:file:`PCBuild/PCbuild.sln` solution in the Python source tree and build the +"x64" configuration of the 'pythoncore' project before cross-compiling +extensions is possible. + +Note that by default, Visual Studio 2008 does not install 64bit compilers or +tools. You may need to reexecute the Visual Studio setup process and select +these tools (using Control Panel->[Add/Remove] Programs is a convenient way to +check or modify your existing install.) + +.. _packaging-postinstallation-script: + +The Postinstallation script +--------------------------- + +Starting with Python 2.3, a postinstallation script can be specified with the +:option:`--install-script` option. The basename of the script must be +specified, and the script filename must also be listed in the scripts argument +to the setup function. + +This script will be run at installation time on the target system after all the +files have been copied, with ``argv[1]`` set to :option:`-install`, and again at +uninstallation time before the files are removed with ``argv[1]`` set to +:option:`-remove`. + +The installation script runs embedded in the windows installer, every output +(``sys.stdout``, ``sys.stderr``) is redirected into a buffer and will be +displayed in the GUI after the script has finished. + +Some functions especially useful in this context are available as additional +built-in functions in the installation script. + +.. currentmodule:: bdist_wininst-postinst-script + +.. function:: directory_created(path) + file_created(path) + + These functions should be called when a directory or file is created by the + postinstall script at installation time. It will register *path* with the + uninstaller, so that it will be removed when the distribution is uninstalled. + To be safe, directories are only removed if they are empty. + + +.. function:: get_special_folder_path(csidl_string) + + This function can be used to retrieve special folder locations on Windows like + the Start Menu or the Desktop. It returns the full path to the folder. + *csidl_string* must be one of the following strings:: + + "CSIDL_APPDATA" + + "CSIDL_COMMON_STARTMENU" + "CSIDL_STARTMENU" + + "CSIDL_COMMON_DESKTOPDIRECTORY" + "CSIDL_DESKTOPDIRECTORY" + + "CSIDL_COMMON_STARTUP" + "CSIDL_STARTUP" + + "CSIDL_COMMON_PROGRAMS" + "CSIDL_PROGRAMS" + + "CSIDL_FONTS" + + If the folder cannot be retrieved, :exc:`OSError` is raised. + + Which folders are available depends on the exact Windows version, and probably + also the configuration. For details refer to Microsoft's documentation of the + c:function:`SHGetSpecialFolderPath` function. + + +.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]]) + + This function creates a shortcut. *target* is the path to the program to be + started by the shortcut. *description* is the description of the shortcut. + *filename* is the title of the shortcut that the user will see. *arguments* + specifies the command-line arguments, if any. *workdir* is the working directory + for the program. *iconpath* is the file containing the icon for the shortcut, + and *iconindex* is the index of the icon in the file *iconpath*. Again, for + details consult the Microsoft documentation for the :class:`IShellLink` + interface. + + +Vista User Access Control (UAC) +=============================== + +Starting with Python 2.6, bdist_wininst supports a :option:`--user-access-control` +option. The default is 'none' (meaning no UAC handling is done), and other +valid values are 'auto' (meaning prompt for UAC elevation if Python was +installed for all users) and 'force' (meaning always prompt for elevation). diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/commandhooks.rst @@ -0,0 +1,31 @@ +============= +Command hooks +============= + +Packaging provides a way of extending its commands by the use of pre- and +post- command hooks. The hooks are simple Python functions (or any callable +objects) and are specified in the config file using their full qualified names. +The pre-hooks are run after the command is finalized (its options are +processed), but before it is run. The post-hooks are run after the command +itself. Both types of hooks receive an instance of the command object. + +Sample usage of hooks +===================== + +Firstly, you need to make sure your hook is present in the path. This is usually +done by dropping them to the same folder where `setup.py` file lives :: + + # file: myhooks.py + def my_install_hook(install_cmd): + print "Oh la la! Someone is installing my project!" + +Then, you need to point to it in your `setup.cfg` file, under the appropriate +command section :: + + [install_dist] + pre-hook.project = myhooks.my_install_hook + +The hooks defined in different config files (system-wide, user-wide and +package-wide) do not override each other as long as they are specified with +different aliases (additional names after the dot). The alias in the example +above is ``project``. diff --git a/Doc/packaging/commandref.rst b/Doc/packaging/commandref.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/commandref.rst @@ -0,0 +1,349 @@ +.. _packaging-command-reference: + +***************** +Command Reference +***************** + +This reference briefly documents all standard Packaging commands and some of +their options. + +.. FIXME does not work: Use pysetup run --help-commands to list all + standard and extra commands availavble on your system, with their + description. Use pysetup run --help to get help about the options + of one command. + + +Preparing distributions +======================= + +:command:`check` +---------------- + +Perform some tests on the metadata of a distribution. + +For example, it verifies that all required metadata fields are provided in the +:file:`setup.cfg` file. + +.. TODO document reST checks + + +:command:`test` +--------------- + +Run a test suite. + +When doing test-driven development, or running automated builds that need +testing before they are installed for downloading or use, it's often useful to +be able to run a project's unit tests without actually installing the project +anywhere. The :command:`test` command runs project's unit tests without +actually installing it, by temporarily putting the project's source on +:data:`sys.path`, after first running :command:`build_ext -i` to ensure that any +C extensions are built. + +You can use this command in one of two ways: either by specifying a +unittest-compatible test suite for your project (or any callable that returns +it) or by passing a test runner function that will run your tests and display +results in the console. Both options take a Python dotted name in the form +``package.module.callable`` to specify the object to use. + +If none of these options are specified, Packaging will try to perform test +discovery using either unittest (for Python 3.2 and higher) or unittest2 (for +older versions, if installed). + +.. this is a pseudo-command name used to disambiguate the options in indexes and + links +.. program:: packaging test + +.. cmdoption:: --suite=NAME, -s NAME + + Specify the test suite (or module, class, or method) to be run. The default + for this option can be set by in the project's :file:`setup.cfg` file:: + + .. code-block:: cfg + + [test] + suite = mypackage.tests.get_all_tests + +.. cmdoption:: --runner=NAME, -r NAME + + Specify the test runner to be called. + + +:command:`config` +----------------- + +Perform distribution configuration. + + +The build step +============== + +This step is mainly useful to compile C/C++ libraries or extension modules. The +build commands can be run manually to check for syntax errors or packaging +issues (for example if the addition of a new source file was forgotten in the +:file:`setup.cfg` file), and is also run automatically by commands which need +it. Packaging checks the mtime of source and built files to avoid re-building +if it's not necessary. + + +:command:`build` +---------------- + +Build all files of a distribution, delegating to the other :command:`build_*` +commands to do the work. + + +:command:`build_clib` +--------------------- + +Build C libraries. + + +:command:`build_ext` +-------------------- + +Build C/C++ extension modules. + + +:command:`build_py` +------------------- + +Build the Python modules (just copy them to the build directory) and +byte-compile them to .pyc files. + + +:command:`build_scripts` +------------------------ +Build the scripts (just copy them to the build directory and adjust their +shebang if they're Python scripts). + + +:command:`clean` +---------------- + +Clean the build tree of the release. + +.. program:: packaging clean + +.. cmdoption:: --all, -a + + Remove build directories for modules, scripts, etc., not only temporary build + by-products. + + +Creating source and built distributions +======================================= + +:command:`sdist` +---------------- + +Build a source distribution for a release. + +It is recommended that you always build and upload a source distribution. Users +of OSes with easy access to compilers and users of advanced packaging tools will +prefer to compile from source rather than using pre-built distributions. For +Windows users, providing a binary installer is also recommended practice. + + +:command:`bdist` +---------------- + +Build a binary distribution for a release. + +This command will call other :command:`bdist_*` commands to create one or more +distributions depending on the options given. The default is to create a +.tar.gz archive on Unix and a zip archive on Windows or OS/2. + +.. program:: packaging bdist + +.. cmdoption:: --formats + + Binary formats to build (comma-separated list). + +.. cmdoption:: --show-formats + + Dump list of available formats. + + +:command:`bdist_dumb` +--------------------- + +Build a "dumb" installer, a simple archive of files that could be unpacked under +``$prefix`` or ``$exec_prefix``. + + +:command:`bdist_wininst` +------------------------ + +Build a Windows installer. + + +:command:`bdist_msi` +-------------------- + +Build a `Microsoft Installer`_ (.msi) file. + +.. _Microsoft Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + +In most cases, the :command:`bdist_msi` installer is a better choice than the +:command:`bdist_wininst` installer, because it provides better support for Win64 +platforms, allows administrators to perform non-interactive installations, and +allows installation through group policies. + + +Publishing distributions +======================== + +:command:`register` +------------------- + +This command registers the current release with the Python Package Index. This +is described in more detail in :PEP:`301`. + +.. TODO explain user and project registration with the web UI + + +:command:`upload` +----------------- + +Upload source and/or binary distributions to PyPI. + +The distributions have to be built on the same command line as the +:command:`upload` command; see :ref:`packaging-package-upload` for more info. + +.. program:: packaging upload + +.. cmdoption:: --sign, -s + + Sign each uploaded file using GPG (GNU Privacy Guard). The ``gpg`` program + must be available for execution on the system ``PATH``. + +.. cmdoption:: --identity=NAME, -i NAME + + Specify the identity or key name for GPG to use when signing. The value of + this option will be passed through the ``--local-user`` option of the + ``gpg`` program. + +.. cmdoption:: --show-response + + Display the full response text from server; this is useful for debugging + PyPI problems. + +.. cmdoption:: --repository=URL, -r URL + + The URL of the repository to upload to. Defaults to + http://pypi.python.org/pypi (i.e., the main PyPI installation). + +.. cmdoption:: --upload-docs + + Also run :command:`upload_docs`. Mainly useful as a default value in + :file:`setup.cfg` (on the command line, it's shorter to just type both + commands). + + +:command:`upload_docs` +---------------------- + +Upload HTML documentation to PyPI. + +PyPI now supports publishing project documentation at a URI of the form +``http://packages.python.org/``. :command:`upload_docs` will create +the necessary zip file out of a documentation directory and will post to the +repository. + +Note that to upload the documentation of a project, the corresponding version +must already be registered with PyPI, using the :command:`register` command --- +just like with :command:`upload`. + +Assuming there is an ``Example`` project with documentation in the subdirectory +:file:`docs`, for example:: + + Example/ + example.py + setup.cfg + docs/ + build/ + html/ + index.html + tips_tricks.html + conf.py + index.txt + tips_tricks.txt + +You can simply specify the directory with the HTML files in your +:file:`setup.cfg` file: + +.. code-block:: cfg + + [upload_docs] + upload-dir = docs/build/html + + +.. program:: packaging upload_docs + +.. cmdoption:: --upload-dir + + The directory to be uploaded to the repository. By default documentation + is searched for in ``docs`` (or ``doc``) directory in project root. + +.. cmdoption:: --show-response + + Display the full response text from server; this is useful for debugging + PyPI problems. + +.. cmdoption:: --repository=URL, -r URL + + The URL of the repository to upload to. Defaults to + http://pypi.python.org/pypi (i.e., the main PyPI installation). + + +The install step +================ + +These commands are used by end-users of a project using :program:`pysetup` or +another compatible installer. Each command will run the corresponding +:command:`build_*` command and then move the built files to their destination on +the target system. + + +:command:`install_dist` +----------------------- + +Install a distribution, delegating to the other :command:`install_*` commands to +do the work. + +.. program:: packaging install_dist + +.. cmdoption:: --user + + Install in user site-packages directory (see :PEP:`370`). + + +:command:`install_data` +----------------------- + +Install data files. + + +:command:`install_distinfo` +--------------------------- + +Install files recording details of the installation as specified in :PEP:`376`. + + +:command:`install_headers` +-------------------------- + +Install C/C++ header files. + + +:command:`install_lib` +---------------------- + +Install C library files. + + +:command:`install_scripts` +-------------------------- + +Install scripts. diff --git a/Doc/packaging/configfile.rst b/Doc/packaging/configfile.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/configfile.rst @@ -0,0 +1,125 @@ +.. _packaging-setup-config: + +************************************ +Writing the Setup Configuration File +************************************ + +Often, it's not possible to write down everything needed to build a distribution +*a priori*: you may need to get some information from the user, or from the +user's system, in order to proceed. As long as that information is fairly +simple---a list of directories to search for C header files or libraries, for +example---then providing a configuration file, :file:`setup.cfg`, for users to +edit is a cheap and easy way to solicit it. Configuration files also let you +provide default values for any command option, which the installer can then +override either on the command line or by editing the config file. + +The setup configuration file is a useful middle-ground between the setup script +---which, ideally, would be opaque to installers [#]_---and the command line to +the setup script, which is outside of your control and entirely up to the +installer. In fact, :file:`setup.cfg` (and any other Distutils configuration +files present on the target system) are processed after the contents of the +setup script, but before the command line. This has several useful +consequences: + +.. If you have more advanced needs, such as determining which extensions to + build based on what capabilities are present on the target system, then you + need the Distutils auto-configuration facility. This started to appear in + Distutils 0.9 but, as of this writing, isn't mature or stable enough yet + for real-world use. + +* installers can override some of what you put in :file:`setup.py` by editing + :file:`setup.cfg` + +* you can provide non-standard defaults for options that are not easily set in + :file:`setup.py` + +* installers can override anything in :file:`setup.cfg` using the command-line + options to :file:`setup.py` + +The basic syntax of the configuration file is simple:: + + [command] + option = value + ... + +where *command* is one of the Distutils commands (e.g. :command:`build_py`, +:command:`install_dist`), and *option* is one of the options that command supports. +Any number of options can be supplied for each command, and any number of +command sections can be included in the file. Blank lines are ignored, as are +comments, which run from a ``'#'`` character until the end of the line. Long +option values can be split across multiple lines simply by indenting the +continuation lines. + +You can find out the list of options supported by a particular command with the +universal :option:`--help` option, e.g. :: + + > python setup.py --help build_ext + [...] + Options for 'build_ext' command: + --build-lib (-b) directory for compiled extension modules + --build-temp (-t) directory for temporary files (build by-products) + --inplace (-i) ignore build-lib and put compiled extensions into the + source directory alongside your pure Python modules + --include-dirs (-I) list of directories to search for header files + --define (-D) C preprocessor macros to define + --undef (-U) C preprocessor macros to undefine + --swig-opts list of SWIG command-line options + [...] + +.. XXX do we want to support ``setup.py --help metadata``? + +Note that an option spelled :option:`--foo-bar` on the command line is spelled +:option:`foo_bar` in configuration files. + +For example, say you want your extensions to be built "in-place"---that is, you +have an extension :mod:`pkg.ext`, and you want the compiled extension file +(:file:`ext.so` on Unix, say) to be put in the same source directory as your +pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the +:option:`--inplace` option on the command line to ensure this:: + + python setup.py build_ext --inplace + +But this requires that you always specify the :command:`build_ext` command +explicitly, and remember to provide :option:`--inplace`. An easier way is to +"set and forget" this option, by encoding it in :file:`setup.cfg`, the +configuration file for this distribution:: + + [build_ext] + inplace = 1 + +This will affect all builds of this module distribution, whether or not you +explicitly specify :command:`build_ext`. If you include :file:`setup.cfg` in +your source distribution, it will also affect end-user builds---which is +probably a bad idea for this option, since always building extensions in-place +would break installation of the module distribution. In certain peculiar cases, +though, modules are built right in their installation directory, so this is +conceivably a useful ability. (Distributing extensions that expect to be built +in their installation directory is almost always a bad idea, though.) + +Another example: certain commands take options that vary from project to +project but not depending on the installation system, for example, +:command:`test` needs to know where your test suite is located and what test +runner to use; likewise, :command:`upload_docs` can find HTML documentation in +a :file:`doc` or :file:`docs` directory, but needs an option to find files in +:file:`docs/build/html`. Instead of having to type out these options each +time you want to run the command, you can put them in the project's +:file:`setup.cfg`:: + + [test] + suite = packaging.tests + + [upload_docs] + upload-dir = docs/build/html + + +.. seealso:: + + :ref:`packaging-config-syntax` in "Installing Python Projects" + More information on the configuration files is available in the manual for + system administrators. + + +.. rubric:: Footnotes + +.. [#] This ideal probably won't be achieved until auto-configuration is fully + supported by the Distutils. diff --git a/Doc/packaging/examples.rst b/Doc/packaging/examples.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/examples.rst @@ -0,0 +1,334 @@ +.. _packaging-examples: + +******** +Examples +******** + +This chapter provides a number of basic examples to help get started with +Packaging. + + +.. _packaging-pure-mod: + +Pure Python distribution (by module) +==================================== + +If you're just distributing a couple of modules, especially if they don't live +in a particular package, you can specify them individually using the +:option:`py_modules` option in the setup script. + +In the simplest case, you'll have two files to worry about: a setup script and +the single module you're distributing, :file:`foo.py` in this example:: + + / + setup.py + foo.py + +(In all diagrams in this section, ** will refer to the distribution root +directory.) A minimal setup script to describe this situation would be:: + + from packaging.core import setup + setup(name='foo', + version='1.0', + py_modules=['foo']) + +Note that the name of the distribution is specified independently with the +:option:`name` option, and there's no rule that says it has to be the same as +the name of the sole module in the distribution (although that's probably a good +convention to follow). However, the distribution name is used to generate +filenames, so you should stick to letters, digits, underscores, and hyphens. + +Since :option:`py_modules` is a list, you can of course specify multiple +modules, e.g. if you're distributing modules :mod:`foo` and :mod:`bar`, your +setup might look like this:: + + / + setup.py + foo.py + bar.py + +and the setup script might be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + py_modules=['foo', 'bar']) + +You can put module source files into another directory, but if you have enough +modules to do that, it's probably easier to specify modules by package rather +than listing them individually. + + +.. _packaging-pure-pkg: + +Pure Python distribution (by package) +===================================== + +If you have more than a couple of modules to distribute, especially if they are +in multiple packages, it's probably easier to specify whole packages rather than +individual modules. This works even if your modules are not in a package; you +can just tell the Distutils to process modules from the root package, and that +works the same as any other package (except that you don't have to have an +:file:`__init__.py` file). + +The setup script from the last example could also be written as :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['']) + +(The empty string stands for the root package.) + +If those two files are moved into a subdirectory, but remain in the root +package, e.g.:: + + / + setup.py + src/ + foo.py + bar.py + +then you would still specify the root package, but you have to tell the +Distutils where source files in the root package live:: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'': 'src'}, + packages=['']) + +More typically, though, you will want to distribute multiple modules in the same +package (or in sub-packages). For example, if the :mod:`foo` and :mod:`bar` +modules belong in package :mod:`foobar`, one way to lay out your source tree is + +:: + + / + setup.py + foobar/ + __init__.py + foo.py + bar.py + +This is in fact the default layout expected by the Distutils, and the one that +requires the least work to describe in your setup script:: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['foobar']) + +If you want to put modules in directories not named for their package, then you +need to use the :option:`package_dir` option again. For example, if the +:file:`src` directory holds modules in the :mod:`foobar` package:: + + / + setup.py + src/ + __init__.py + foo.py + bar.py + +an appropriate setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'foobar': 'src'}, + packages=['foobar']) + +Or, you might put modules from your main package right in the distribution +root:: + + / + setup.py + __init__.py + foo.py + bar.py + +in which case your setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'foobar': ''}, + packages=['foobar']) + +(The empty string also stands for the current directory.) + +If you have sub-packages, they must be explicitly listed in :option:`packages`, +but any entries in :option:`package_dir` automatically extend to sub-packages. +(In other words, the Distutils does *not* scan your source tree, trying to +figure out which directories correspond to Python packages by looking for +:file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: + + / + setup.py + foobar/ + __init__.py + foo.py + bar.py + subfoo/ + __init__.py + blah.py + +then the corresponding setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['foobar', 'foobar.subfoo']) + +(Again, the empty string in :option:`package_dir` stands for the current +directory.) + + +.. _packaging-single-ext: + +Single extension module +======================= + +Extension modules are specified using the :option:`ext_modules` option. +:option:`package_dir` has no effect on where extension source files are found; +it only affects the source for pure Python modules. The simplest case, a +single extension module in a single C source file, is:: + + / + setup.py + foo.c + +If the :mod:`foo` extension belongs in the root package, the setup script for +this could be :: + + from packaging.core import setup, Extension + setup(name='foobar', + version='1.0', + ext_modules=[Extension('foo', ['foo.c'])]) + +If the extension actually belongs in a package, say :mod:`foopkg`, then + +With exactly the same source tree layout, this extension can be put in the +:mod:`foopkg` package simply by changing the name of the extension:: + + from packaging.core import setup, Extension + setup(name='foobar', + version='1.0', + packages=['foopkg'], + ext_modules=[Extension('foopkg.foo', ['foo.c'])]) + + +Checking metadata +================= + +The ``check`` command allows you to verify if your project's metadata +meets the minimum requirements to build a distribution. + +To run it, just call it using your :file:`setup.py` script. If something is +missing, ``check`` will display a warning. + +Let's take an example with a simple script:: + + from packaging.core import setup + + setup(name='foobar') + +.. TODO configure logging StreamHandler to match this output + +Running the ``check`` command will display some warnings:: + + $ python setup.py check + running check + warning: check: missing required metadata: version, home_page + warning: check: missing metadata: either (author and author_email) or + (maintainer and maintainer_email) must be supplied + + +If you use the reStructuredText syntax in the ``long_description`` field and +`Docutils `_ is installed you can check if +the syntax is fine with the ``check`` command, using the ``restructuredtext`` +option. + +For example, if the :file:`setup.py` script is changed like this:: + + from packaging.core import setup + + desc = """\ + Welcome to foobar! + =============== + + This is the description of the ``foobar`` project. + """ + + setup(name='foobar', + version='1.0', + author=u'Tarek Ziad?', + author_email='tarek at ziade.org', + summary='Foobar utilities' + description=desc, + home_page='http://example.com') + +Where the long description is broken, ``check`` will be able to detect it +by using the :mod:`docutils` parser:: + + $ python setup.py check --restructuredtext + running check + warning: check: Title underline too short. (line 2) + warning: check: Could not finish the parsing. + + +.. _packaging-reading-metadata: + +Reading the metadata +==================== + +The :func:`packaging.core.setup` function provides a command-line interface +that allows you to query the metadata fields of a project through the +:file:`setup.py` script of a given project:: + + $ python setup.py --name + foobar + +This call reads the ``name`` metadata by running the +:func:`packaging.core.setup` function. When a source or binary +distribution is created with Distutils, the metadata fields are written +in a static file called :file:`PKG-INFO`. When a Distutils-based project is +installed in Python, the :file:`PKG-INFO` file is copied alongside the modules +and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, +where ``NAME`` is the name of the project, ``VERSION`` its version as defined +in the Metadata, and ``pyX.X`` the major and minor version of Python like +``2.7`` or ``3.2``. + +You can read back this static file, by using the +:class:`packaging.dist.Metadata` class and its +:func:`read_pkg_file` method:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata() + >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) + >>> metadata.name + 'distribute' + >>> metadata.version + '0.6.8' + >>> metadata.description + 'Easily download, build, install, upgrade, and uninstall Python packages' + +Notice that the class can also be instantiated with a metadata file path to +loads its values:: + + >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' + >>> Metadata(pkg_info_path).name + 'distribute' + + +.. XXX These comments have been here for at least ten years. Write the + sections or delete the comments (we can maybe ask Greg Ward about + the planned contents). (Unindent to make them section titles) + + .. multiple-ext:: + + Multiple extension modules + ========================== + + Putting it all together + ======================= diff --git a/Doc/packaging/extending.rst b/Doc/packaging/extending.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/extending.rst @@ -0,0 +1,95 @@ +.. _extending-packaging: + +******************* +Extending Distutils +******************* + +Distutils can be extended in various ways. Most extensions take the form of new +commands or replacements for existing commands. New commands may be written to +support new types of platform-specific packaging, for example, while +replacements for existing commands may be made to modify details of how the +command operates on a package. + +Most extensions of the packaging are made within :file:`setup.py` scripts that +want to modify existing commands; many simply add a few file extensions that +should be copied into packages in addition to :file:`.py` files as a +convenience. + +Most packaging command implementations are subclasses of the +:class:`packaging.cmd.Command` class. New commands may directly inherit from +:class:`Command`, while replacements often derive from :class:`Command` +indirectly, directly subclassing the command they are replacing. Commands are +required to derive from :class:`Command`. + +.. .. _extend-existing: + Extending existing commands + =========================== + + +.. .. _new-commands: + Writing new commands + ==================== + + +Integrating new commands +======================== + +There are different ways to integrate new command implementations into +packaging. The most difficult is to lobby for the inclusion of the new features +in packaging itself, and wait for (and require) a version of Python that +provides that support. This is really hard for many reasons. + +The most common, and possibly the most reasonable for most needs, is to include +the new implementations with your :file:`setup.py` script, and cause the +:func:`packaging.core.setup` function use them:: + + from packaging.core import setup + from packaging.command.build_py import build_py as _build_py + + class build_py(_build_py): + """Specialized Python source builder.""" + + # implement whatever needs to be different... + + setup(..., cmdclass={'build_py': build_py}) + +This approach is most valuable if the new implementations must be used to use a +particular package, as everyone interested in the package will need to have the +new command implementation. + +Beginning with Python 2.4, a third option is available, intended to allow new +commands to be added which can support existing :file:`setup.py` scripts without +requiring modifications to the Python installation. This is expected to allow +third-party extensions to provide support for additional packaging systems, but +the commands can be used for anything packaging commands can be used for. A new +configuration option, :option:`command_packages` (command-line option +:option:`--command-packages`), can be used to specify additional packages to be +searched for modules implementing commands. Like all packaging options, this +can be specified on the command line or in a configuration file. This option +can only be set in the ``[global]`` section of a configuration file, or before +any commands on the command line. If set in a configuration file, it can be +overridden from the command line; setting it to an empty string on the command +line causes the default to be used. This should never be set in a configuration +file provided with a package. + +This new option can be used to add any number of packages to the list of +packages searched for command implementations; multiple package names should be +separated by commas. When not specified, the search is only performed in the +:mod:`packaging.command` package. When :file:`setup.py` is run with the option +:option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages +:mod:`packaging.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched +in that order. New commands are expected to be implemented in modules of the +same name as the command by classes sharing the same name. Given the example +command-line option above, the command :command:`bdist_openpkg` could be +implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or +:class:`buildcmds.bdist_openpkg.bdist_openpkg`. + + +Adding new distribution types +============================= + +Commands that create distributions (files in the :file:`dist/` directory) need +to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that +:command:`upload` can upload it to PyPI. The *filename* in the pair contains no +path information, only the name of the file itself. In dry-run mode, pairs +should still be added to represent what would have been created. diff --git a/Doc/packaging/index.rst b/Doc/packaging/index.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/index.rst @@ -0,0 +1,45 @@ +.. _packaging-index: + +############################## + Distributing Python Projects +############################## + +:Authors: Greg Ward, Anthony Baxter and Packaging contributors +:Email: distutils-sig at python.org +:Release: |version| +:Date: |today| + +This document describes Packaging for Python authors, describing how to use the +module to make Python applications, packages or modules easily available to a +wider audience with very little overhead for build/release/install mechanics. + +.. toctree:: + :maxdepth: 2 + :numbered: + + tutorial + setupcfg + introduction + setupscript + configfile + sourcedist + builtdist + packageindex + uploading + examples + extending + commandhooks + commandref + + +.. seealso:: + + :ref:`packaging-install-index` + A user-centered manual which includes information on adding projects + into an existing Python installation. You do not need to be a Python + programmer to read this manual. + + :mod:`packaging` + A library reference for developers of packaging tools wanting to use + standalone building blocks like :mod:`~packaging.version` or + :mod:`~packaging.metadata`, or extend Packaging itself. diff --git a/Doc/packaging/introduction.rst b/Doc/packaging/introduction.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/introduction.rst @@ -0,0 +1,193 @@ +.. _packaging-intro: + +***************************** +An Introduction to Packaging +***************************** + +This document covers using Packaging to distribute your Python modules, +concentrating on the role of developer/distributor. If you're looking for +information on installing Python modules you should refer to the +:ref:`packaging-install-index` chapter. + +Throughout this documentation, the terms "Distutils", "the Distutils" and +"Packaging" will be used interchangeably. + +.. _packaging-concepts: + +Concepts & Terminology +====================== + +Using Distutils is quite simple both for module developers and for +users/administrators installing third-party modules. As a developer, your +responsibilities (apart from writing solid, well-documented and well-tested +code, of course!) are: + +* writing a setup script (:file:`setup.py` by convention) + +* (optional) writing a setup configuration file + +* creating a source distribution + +* (optional) creating one or more "built" (binary) distributions of your + project + +All of these tasks are covered in this document. + +Not all module developers have access to multiple platforms, so one cannot +expect them to create buildt distributions for every platform. To remedy +this, it is hoped that intermediaries called *packagers* will arise to address +this need. Packagers take source distributions released by module developers, +build them on one or more platforms and release the resulting built +distributions. Thus, users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their +platform without having to run a setup script or compile a single line of code. + + +.. _packaging-simple-example: + +A Simple Example +================ + +A setup script is usually quite simple, although since it's written in Python +there are no arbitrary limits to what you can do with it, though you should be +careful about putting expensive operations in your setup script. +Unlike, say, Autoconf-style configure scripts the setup script may be run +multiple times in the course of building and installing a module +distribution. + +If all you want to do is distribute a module called :mod:`foo`, contained in a +file :file:`foo.py`, then your setup script can be as simple as:: + + from packaging.core import setup + setup(name='foo', + version='1.0', + py_modules=['foo']) + +Some observations: + +* most information that you supply to the Distutils is supplied as keyword + arguments to the :func:`setup` function + +* those keyword arguments fall into two categories: package metadata (name, + version number, etc.) and information about what's in the package (a list + of pure Python modules in this case) + +* modules are specified by module name, not filename (the same will hold true + for packages and extensions) + +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the + project if appropriate (see section :ref:`packaging-setup-script` for an example) + +To create a source distribution for this module you would create a setup +script, :file:`setup.py`, containing the above code and run:: + + python setup.py sdist + +which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +containing your setup script :file:`setup.py`, and your module :file:`foo.py`. +The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and +will unpack into a directory :file:`foo-1.0`. + +If an end-user wishes to install your :mod:`foo` module all he has to do is +download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and from the +:file:`foo-1.0` directory run :: + + python setup.py install + +which will copy :file:`foo.py` to the appropriate directory for +third-party modules in their Python installation. + +This simple example demonstrates some fundamental concepts of Distutils. +First, both developers and installers have the same basic user interface, i.e. +the setup script. The difference is which Distutils *commands* they use: the +:command:`sdist` command is almost exclusively for module developers, while +:command:`install` is more often used by installers (although some developers +will want to install their own code occasionally). + +If you want to make things really easy for your users, you can create more +than one built distributions for them. For instance, if you are running on a +Windows machine and want to make things easy for other Windows users, you can +create an executable installer (the most appropriate type of built distribution +for this platform) with the :command:`bdist_wininst` command. For example:: + + python setup.py bdist_wininst + +will create an executable installer, :file:`foo-1.0.win32.exe`, in the current +directory. You can find out what distribution formats are available at any time +by running :: + + python setup.py bdist --help-formats + + +.. _packaging-python-terms: + +General Python terminology +========================== + +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that +everyone is on the same page, here's a quick overview of Python terms: + +module + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure + Python modules, extension modules and packages. + +pure Python module + A module written in Python and contained in a single :file:`.py` file (and + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + referred to as a "pure module." + +extension module + A module written in the low-level language of the Python implementation: C/C++ + for Python, Java for Jython. Typically contained in a single dynamically + loaded pre-compiled file, e.g. a shared object (:file:`.so`) file for Python + extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python + extensions on Windows, or a Java class file for Jython extensions. Note that + currently Distutils only handles C/C++ extensions for Python. + +package + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a + file :file:`__init__.py`. + +root package + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root + package. + + +.. _packaging-term: + +Distutils-specific terminology +============================== + +The following terms apply more specifically to the domain of distributing Python +modules using Distutils: + +module distribution + A collection of Python modules distributed together as a single downloadable + resource and meant to be installed all as one. Examples of some well-known + module distributions are NumPy, SciPy, PIL (the Python Imaging + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module + distribution may contain zero, one, or many Python packages.) + +pure module distribution + A module distribution that contains only pure Python modules and packages. + Sometimes referred to as a "pure distribution." + +non-pure module distribution + A module distribution that contains at least one extension module. Sometimes + referred to as a "non-pure distribution." + +distribution root + The top-level directory of your source tree (or source distribution). The + directory where :file:`setup.py` exists. Generally :file:`setup.py` will + be run from this directory. diff --git a/Doc/packaging/packageindex.rst b/Doc/packaging/packageindex.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/packageindex.rst @@ -0,0 +1,104 @@ +.. _packaging-package-index: + +********************************** +Registering with the Package Index +********************************** + +The Python Package Index (PyPI) holds metadata describing distributions +packaged with packaging. The packaging command :command:`register` is used to +submit your distribution's metadata to the index. It is invoked as follows:: + + python setup.py register + +Distutils will respond with the following prompt:: + + running register + We need to know who you are, so please choose either: + 1. use your existing login, + 2. register as a new user, + 3. have the server generate a new password for you (and email it to you), or + 4. quit + Your selection [default 1]: + +Note: if your username and password are saved locally, you will not see this +menu. + +If you have not registered with PyPI, then you will need to do so now. You +should choose option 2, and enter your details as required. Soon after +submitting your details, you will receive an email which will be used to confirm +your registration. + +Once you are registered, you may choose option 1 from the menu. You will be +prompted for your PyPI username and password, and :command:`register` will then +submit your metadata to the index. + +You may submit any number of versions of your distribution to the index. If you +alter the metadata for a particular version, you may submit it again and the +index will be updated. + +PyPI holds a record for each (name, version) combination submitted. The first +user to submit information for a given name is designated the Owner of that +name. They may submit changes through the :command:`register` command or through +the web interface. They may also designate other users as Owners or Maintainers. +Maintainers may edit the package information, but not designate other Owners or +Maintainers. + +By default PyPI will list all versions of a given package. To hide certain +versions, the Hidden property should be set to yes. This must be edited through +the web interface. + + +.. _packaging-pypirc: + +The .pypirc file +================ + +The format of the :file:`.pypirc` file is as follows:: + + [packaging] + index-servers = + pypi + + [pypi] + repository: + username: + password: + +The *packaging* section defines a *index-servers* variable that lists the +name of all sections describing a repository. + +Each section describing a repository defines three variables: + +- *repository*, that defines the url of the PyPI server. Defaults to + ``http://www.python.org/pypi``. +- *username*, which is the registered username on the PyPI server. +- *password*, that will be used to authenticate. If omitted the user + will be prompt to type it when needed. + +If you want to define another server a new section can be created and +listed in the *index-servers* variable:: + + [packaging] + index-servers = + pypi + other + + [pypi] + repository: + username: + password: + + [other] + repository: http://example.com/pypi + username: + password: + +:command:`register` can then be called with the -r option to point the +repository to work with:: + + python setup.py register -r http://example.com/pypi + +For convenience, the name of the section that describes the repository +may also be used:: + + python setup.py register -r other diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/setupcfg.rst @@ -0,0 +1,648 @@ +.. highlightlang:: cfg + +******************************************* +Specification of the :file:`setup.cfg` file +******************************************* + +.. :version: 1.0 + +This document describes the :file:`setup.cfg`, an ini-style configuration file +(compatible with :class:`configparser.RawConfigParser`) configuration file used +by Packaging to replace the :file:`setup.py` file. + +Each section contains a description of its options. + +- Options that are marked *multi* can have multiple values, one value per + line. +- Options that are marked *optional* can be omitted. +- Options that are marked *environ* can use environment markers, as described + in :PEP:`345`. + + +The sections are: + +global + Global options not related to one command. + +metadata + Name, version and other information defined by :PEP:`345`. + +files + Modules, scripts, data, documentation and other files to include in the + distribution. + +command sections + Options given for specific commands, identical to those that can be given + on the command line. + + +Global options +============== + +Contains global options for Packaging. This section is shared with Distutils. + + +commands + Defined Packaging command. A command is defined by its fully + qualified name. *optional*, *multi* + + Examples:: + + [global] + commands = + package.setup.CustomSdistCommand + package.setup.BdistDeb + +compilers + Defined Packaging compiler. A compiler is defined by its fully + qualified name. *optional*, *multi* + + Example:: + + [global] + compilers = + hotcompiler.SmartCCompiler + +setup_hook + defines a callable that will be called right after the + :file:`setup.cfg` file is read. The callable receives the configuration + in form of a mapping and can make some changes to it. *optional* + + Example:: + + [global] + setup_hook = package.setup.customize_dist + + +Metadata +======== + +The metadata section contains the metadata for the project as described in +:PEP:`345`. Field names are case-insensitive. + +Fields: + +name + Name of the project. + +version + Version of the project. Must comply with :PEP:`386`. + +platform + Platform specification describing an operating system + supported by the distribution which is not listed in the "Operating System" + Trove classifiers (:PEP:`301`). *optional*, *multi* + +supported-platform + Binary distributions containing a PKG-INFO file will + use the Supported-Platform field in their metadata to specify the OS and + CPU for which the binary distribution was compiled. The semantics of + the Supported-Platform field are free form. *optional*, *multi* + +summary + A one-line summary of what the distribution does. + (Used to be called *description* in Distutils1.) + +description + A longer description. (Used to be called *long_description* + in Distutils1.) A file can be provided in the *description-file* field. + *optional* + +description-file + path to a text file that will be used for the + **description** field. *optional* + +keywords + A list of additional keywords to be used to assist searching + for the distribution in a larger catalog. Comma or space-separated. + *optional* + +home-page + The URL for the distribution's home page. + +download-url + The URL from which this version of the distribution + can be downloaded. *optional* + +author + Author's name. *optional* + +author-email + Author's e-mail. *optional* + +maintainer + Maintainer's name. *optional* + +maintainer-email + Maintainer's e-mail. *optional* + +license + A text indicating the term of uses, when a trove classifier does + not match. *optional*. + +classifiers + Classification for the distribution, as described in PEP 301. + *optional*, *multi*, *environ* + +requires-dist + name of another packaging project required as a dependency. + The format is *name (version)* where version is an optional + version declaration, as described in PEP 345. *optional*, *multi*, *environ* + +provides-dist + name of another packaging project contained within this + distribution. Same format than *requires-dist*. *optional*, *multi*, + *environ* + +obsoletes-dist + name of another packaging project this version obsoletes. + Same format than *requires-dist*. *optional*, *multi*, *environ* + +requires-python + Specifies the Python version the distribution requires. + The value is a version number, as described in PEP 345. + *optional*, *multi*, *environ* + +requires-externals + a dependency in the system. This field is free-form, + and just a hint for downstream maintainers. *optional*, *multi*, + *environ* + +project-url + A label, followed by a browsable URL for the project. + "label, url". The label is limited to 32 signs. *optional*, *multi* + + +Example:: + + [metadata] + name = pypi2rpm + version = 0.1 + author = Tarek Ziad? + author-email = tarek at ziade.org + summary = Script that transforms an sdist archive into a RPM package + description-file = README + home-page = http://bitbucket.org/tarek/pypi2rpm/wiki/Home + project-url: + Repository, http://bitbucket.org/tarek/pypi2rpm/ + RSS feed, https://bitbucket.org/tarek/pypi2rpm/rss + classifier = + Development Status :: 3 - Alpha + License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1) + +You should not give any explicit value for metadata-version: it will be guessed +from the fields present in the file. + + +Files +===== + +This section describes the files included in the project. + +packages_root + the root directory containing all packages and modules + (default: current directory). *optional* + +packages + a list of packages the project includes *optional*, *multi* + +modules + a list of packages the project includes *optional*, *multi* + +scripts + a list of scripts the project includes *optional*, *multi* + +extra_files + a list of patterns to include extra files *optional*, + *multi* + +Example:: + + [files] + packages_root = src + packages = + pypi2rpm + pypi2rpm.command + + scripts = + pypi2rpm/pypi2rpm.py + + extra_files = + setup.py + README + + +.. Note:: + The :file:`setup.cfg` configuration file is included by default. Contrary to + Distutils, :file:`README` (or :file:`README.txt`) and :file:`setup.py` are + not included by default. + + +Resources +--------- + +This section describes the files used by the project which must not be installed +in the same place that python modules or libraries, they are called +**resources**. They are for example documentation files, script files, +databases, etc... + +For declaring resources, you must use this notation:: + + source = destination + +Data-files are declared in the **resources** field in the **file** section, for +example:: + + [files] + resources = + source1 = destination1 + source2 = destination2 + +The **source** part of the declaration are relative paths of resources files +(using unix path separator **/**). For example, if you've this source tree:: + + foo/ + doc/ + doc.man + scripts/ + foo.sh + +Your setup.cfg will look like:: + + [files] + resources = + doc/doc.man = destination_doc + scripts/foo.sh = destination_scripts + +The final paths where files will be placed are composed by : **source** + +**destination**. In the previous example, **doc/doc.man** will be placed in +**destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in +**destination_scripts/scripts/foo.sh**. (If you want more control on the final +path, take a look at base_prefix_). + +The **destination** part of resources declaration are paths with categories. +Indeed, it's generally a bad idea to give absolute path as it will be cross +incompatible. So, you must use resources categories in your **destination** +declaration. Categories will be replaced by their real path at the installation +time. Using categories is all benefit, your declaration will be simpler, cross +platform and it will allow packager to place resources files where they want +without breaking your code. + +Categories can be specified by using this syntax:: + + {category} + +Default categories are: + +* config +* appdata +* appdata.arch +* appdata.persistent +* appdata.disposable +* help +* icon +* scripts +* doc +* info +* man + +A special category also exists **{distribution.name}** that will be replaced by +the name of the distribution, but as most of the defaults categories use them, +so it's not necessary to add **{distribution.name}** into your destination. + +If you use categories in your declarations, and you are encouraged to do, final +path will be:: + + source + destination_expanded + +.. _example_final_path: + +For example, if you have this setup.cfg:: + + [metadata] + name = foo + + [files] + resources = + doc/doc.man = {doc} + +And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final +path will be:: + + {datadir}/doc/foo/doc/doc.man + +Where {datafir} category will be platform-dependent. + + +More control on source part +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Glob syntax +""""""""""" + +When you declare source file, you can use a glob-like syntax to match multiples file, for example:: + + scripts/* = {script} + +Will match all the files in the scripts directory and placed them in the script category. + +Glob tokens are: + + * ``*``: match all files. + * ``?``: match any character. + * ``**``: match any level of tree recursion (even 0). + * ``{}``: will match any part separated by comma (example: ``{sh,bat}``). + +.. TODO Add examples + +Order of declaration +"""""""""""""""""""" + +The order of declaration is important if one file match multiple rules. The last +rules matched by file is used, this is useful if you have this source tree:: + + foo/ + doc/ + index.rst + setup.rst + documentation.txt + doc.tex + README + +And you want all the files in the doc directory to be placed in {doc} category, +but README must be placed in {help} category, instead of listing all the files +one by one, you can declare them in this way:: + + [files] + resources = + doc/* = {doc} + doc/README = {help} + +Exclude +""""""" + +You can exclude some files of resources declaration by giving no destination, it +can be useful if you have a non-resources file in the same directory of +resources files:: + + foo/ + doc/ + RELEASES + doc.tex + documentation.txt + docu.rst + +Your **files** section will be:: + + [files] + resources = + doc/* = {doc} + doc/RELEASES = + +More control on destination part +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _base_prefix: + +Defining a base prefix +"""""""""""""""""""""" + +When you define your resources, you can have more control of how the final path +is compute. + +By default, the final path is:: + + destination + source + +This can generate long paths, for example (example_final_path_):: + + {datadir}/doc/foo/doc/doc.man + +When you declare your source, you can use whitespace to split the source in +**prefix** **suffix**. So, for example, if you have this source:: + + docs/ doc.man + +The **prefix** is "docs/" and the **suffix** is "doc.html". + +.. note:: + + Separator can be placed after a path separator or replace it. So these two + sources are equivalent:: + + docs/ doc.man + docs doc.man + +.. note:: + + Glob syntax is working the same way with standard source and splitted source. + So these rules:: + + docs/* + docs/ * + docs * + + Will match all the files in the docs directory. + +When you use splitted source, the final path is compute in this way:: + + destination + prefix + +So for example, if you have this setup.cfg:: + + [metadata] + name = foo + + [files] + resources = + doc/ doc.man = {doc} + +And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final +path will be:: + + {datadir}/doc/foo/doc.man + + +Overwriting paths for categories +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This part is intended for system administrators or downstream OS packagers. + +The real paths of categories are registered in the *sysconfig.cfg* file +installed in your python installation. This file uses an ini format too. +The content of the file is organized into several sections: + +* globals: Standard categories's paths. +* posix_prefix: Standard paths for categories and installation paths for posix + system. +* other ones XXX + +Standard categories paths are platform independent, they generally refers to +other categories, which are platform dependent. :mod:`sysconfig` will choose +these category from sections matching os.name. For example:: + + doc = {datadir}/doc/{distribution.name} + +It refers to datadir category, which can be different between platforms. In +posix system, it may be:: + + datadir = /usr/share + +So the final path will be:: + + doc = /usr/share/doc/{distribution.name} + +The platform-dependent categories are: + +* confdir +* datadir +* libdir +* base + + +Defining extra categories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. TODO + + +Examples +^^^^^^^^ + +These examples are incremental but work unitarily. + +Resources in root dir +""""""""""""""""""""" + +Source tree:: + + babar-1.0/ + README + babar.sh + launch.sh + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + *.sh = {scripts} + +So babar.sh and launch.sh will be placed in {scripts} directory. + +Now let's move all the scripts into a scripts directory. + +Resources in sub-directory +"""""""""""""""""""""""""" + +Source tree:: + + babar-1.1/ + README + scripts/ + babar.sh + launch.sh + LAUNCH + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.sh = {scripts} + +It's important to use the separator after scripts/ to install all the shell +scripts into {scripts} instead of {scripts}/scripts. + +Now let's add some docs. + +Resources in multiple sub-directories +""""""""""""""""""""""""""""""""""""" + +Source tree:: + + babar-1.2/ + README + scripts/ + babar.sh + launch.sh + LAUNCH + docs/ + api + man + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.sh = {scripts} + doc/ * = {doc} + doc/ man = {man} + +You want to place all the file in the docs script into {doc} category, instead +of man, which must be placed into {man} category, we will use the order of +declaration of globs to choose the destination, the last glob that match the +file is used. + +Now let's add some scripts for windows users. + +Complete example +"""""""""""""""" + +Source tree:: + + babar-1.3/ + README + doc/ + api + man + scripts/ + babar.sh + launch.sh + babar.bat + launch.bat + LAUNCH + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.{sh,bat} = {scripts} + doc/ * = {doc} + doc/ man = {man} + +We use brace expansion syntax to place all the shell and batch scripts into +{scripts} category. + + +Command sections +================ + +To pass options to commands without having to type them on the command line +for each invocation, you can write them in the :file:`setup.cfg` file, in a +section named after the command. Example:: + + [sdist] + # special function to add custom files + manifest-builders = package.setup.list_extra_files + + [build] + use-2to3 = True + + [build_ext] + inplace = on + + [check] + strict = on + all = on + +Option values given in the configuration file can be overriden on the command +line. See :ref:`packaging-setup-config` for more information. diff --git a/Doc/packaging/setupscript.rst b/Doc/packaging/setupscript.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/setupscript.rst @@ -0,0 +1,689 @@ +.. _packaging-setup-script: + +************************ +Writing the Setup Script +************************ + +The setup script is the center of all activity in building, distributing, and +installing modules using Distutils. The main purpose of the setup script is +to describe your module distribution to Distutils, so that the various +commands that operate on your modules do the right thing. As we saw in section +:ref:`packaging-simple-example`, the setup script consists mainly of a +call to :func:`setup` where the most information is supplied as +keyword arguments to :func:`setup`. + +Here's a slightly more involved example, which we'll follow for the next couple +of sections: a setup script that could be used for Packaging itself:: + + #!/usr/bin/env python + + from packaging.core import setup, find_packages + + setup(name='Packaging', + version='1.0', + summary='Python Distribution Utilities', + keywords=['packaging', 'packaging'], + author=u'Tarek Ziad?', + author_email='tarek at ziade.org', + home_page='http://bitbucket.org/tarek/packaging/wiki/Home', + license='PSF', + packages=find_packages()) + + +There are only two differences between this and the trivial one-file +distribution presented in section :ref:`packaging-simple-example`: more +metadata and the specification of pure Python modules by package rather than +by module. This is important since Ristutils consist of a couple of dozen +modules split into (so far) two packages; an explicit list of every module +would be tedious to generate and difficult to maintain. For more information +on the additional metadata, see section :ref:`packaging-metadata`. + +Note that any pathnames (files or directories) supplied in the setup script +should be written using the Unix convention, i.e. slash-separated. The +Distutils will take care of converting this platform-neutral representation into +whatever is appropriate on your current platform before actually using the +pathname. This makes your setup script portable across operating systems, which +of course is one of the major goals of the Distutils. In this spirit, all +pathnames in this document are slash-separated. + +This, of course, only applies to pathnames given to Distutils functions. If +you, for example, use standard Python functions such as :func:`glob.glob` or +:func:`os.listdir` to specify files, you should be careful to write portable +code instead of hardcoding path separators:: + + glob.glob(os.path.join('mydir', 'subdir', '*.html')) + os.listdir(os.path.join('mydir', 'subdir')) + + +.. _packaging-listing-packages: + +Listing whole packages +====================== + +The :option:`packages` option tells the Distutils to process (build, distribute, +install, etc.) all pure Python modules found in each package mentioned in the +:option:`packages` list. In order to do this, of course, there has to be a +correspondence between package names and directories in the filesystem. The +default correspondence is the most obvious one, i.e. package :mod:`packaging` is +found in the directory :file:`packaging` relative to the distribution root. +Thus, when you say ``packages = ['foo']`` in your setup script, you are +promising that the Distutils will find a file :file:`foo/__init__.py` (which +might be spelled differently on your system, but you get the idea) relative to +the directory where your setup script lives. If you break this promise, the +Distutils will issue a warning but still process the broken package anyways. + +If you use a different convention to lay out your source directory, that's no +problem: you just have to supply the :option:`package_dir` option to tell the +Distutils about your convention. For example, say you keep all Python source +under :file:`lib`, so that modules in the "root package" (i.e., not in any +package at all) are in :file:`lib`, modules in the :mod:`foo` package are in +:file:`lib/foo`, and so forth. Then you would put :: + + package_dir = {'': 'lib'} + +in your setup script. The keys to this dictionary are package names, and an +empty package name stands for the root package. The values are directory names +relative to your distribution root. In this case, when you say ``packages = +['foo']``, you are promising that the file :file:`lib/foo/__init__.py` exists. + +Another possible convention is to put the :mod:`foo` package right in +:file:`lib`, the :mod:`foo.bar` package in :file:`lib/bar`, etc. This would be +written in the setup script as :: + + package_dir = {'foo': 'lib'} + +A ``package: dir`` entry in the :option:`package_dir` dictionary implicitly +applies to all packages below *package*, so the :mod:`foo.bar` case is +automatically handled here. In this example, having ``packages = ['foo', +'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and +:file:`lib/bar/__init__.py`. (Keep in mind that although :option:`package_dir` +applies recursively, you must explicitly list all packages in +:option:`packages`: the Distutils will *not* recursively scan your source tree +looking for any directory with an :file:`__init__.py` file.) + + +.. _packaging-listing-modules: + +Listing individual modules +========================== + +For a small module distribution, you might prefer to list all modules rather +than listing packages---especially the case of a single module that goes in the +"root package" (i.e., no package at all). This simplest case was shown in +section :ref:`packaging-simple-example`; here is a slightly more involved +example:: + + py_modules = ['mod1', 'pkg.mod2'] + +This describes two modules, one of them in the "root" package, the other in the +:mod:`pkg` package. Again, the default package/directory layout implies that +these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and +that :file:`pkg/__init__.py` exists as well. And again, you can override the +package/directory correspondence using the :option:`package_dir` option. + + +.. _packaging-describing-extensions: + +Describing extension modules +============================ + +Just as writing Python extension modules is a bit more complicated than writing +pure Python modules, describing them to the Distutils is a bit more complicated. +Unlike pure modules, it's not enough just to list modules or packages and expect +the Distutils to go out and find the right files; you have to specify the +extension name, source file(s), and any compile/link requirements (include +directories, libraries to link with, etc.). + +.. XXX read over this section + +All of this is done through another keyword argument to :func:`setup`, the +:option:`ext_modules` option. :option:`ext_modules` is just a list of +:class:`Extension` instances, each of which describes a single extension module. +Suppose your distribution includes a single extension, called :mod:`foo` and +implemented by :file:`foo.c`. If no additional instructions to the +compiler/linker are needed, describing this extension is quite simple:: + + Extension('foo', ['foo.c']) + +The :class:`Extension` class can be imported from :mod:`packaging.core` along +with :func:`setup`. Thus, the setup script for a module distribution that +contains only this one extension and nothing else might be:: + + from packaging.core import setup, Extension + setup(name='foo', + version='1.0', + ext_modules=[Extension('foo', ['foo.c'])]) + +The :class:`Extension` class (actually, the underlying extension-building +machinery implemented by the :command:`build_ext` command) supports a great deal +of flexibility in describing Python extensions, which is explained in the +following sections. + + +Extension names and packages +---------------------------- + +The first argument to the :class:`Extension` constructor is always the name of +the extension, including any package names. For example, :: + + Extension('foo', ['src/foo1.c', 'src/foo2.c']) + +describes an extension that lives in the root package, while :: + + Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c']) + +describes the same extension in the :mod:`pkg` package. The source files and +resulting object code are identical in both cases; the only difference is where +in the filesystem (and therefore where in Python's namespace hierarchy) the +resulting extension lives. + +If you have a number of extensions all in the same package (or all under the +same base package), use the :option:`ext_package` keyword argument to +:func:`setup`. For example, :: + + setup(..., + ext_package='pkg', + ext_modules=[Extension('foo', ['foo.c']), + Extension('subpkg.bar', ['bar.c'])]) + +will compile :file:`foo.c` to the extension :mod:`pkg.foo`, and :file:`bar.c` to +:mod:`pkg.subpkg.bar`. + + +Extension source files +---------------------- + +The second argument to the :class:`Extension` constructor is a list of source +files. Since the Distutils currently only support C, C++, and Objective-C +extensions, these are normally C/C++/Objective-C source files. (Be sure to use +appropriate extensions to distinguish C++\ source files: :file:`.cc` and +:file:`.cpp` seem to be recognized by both Unix and Windows compilers.) + +However, you can also include SWIG interface (:file:`.i`) files in the list; the +:command:`build_ext` command knows how to deal with SWIG extensions: it will run +SWIG on the interface file and compile the resulting C/C++ file into your +extension. + +.. XXX SWIG support is rough around the edges and largely untested! + +This warning notwithstanding, options to SWIG can be currently passed like +this:: + + setup(..., + ext_modules=[Extension('_foo', ['foo.i'], + swig_opts=['-modern', '-I../include'])], + py_modules=['foo']) + +Or on the command line like this:: + + > python setup.py build_ext --swig-opts="-modern -I../include" + +On some platforms, you can include non-source files that are processed by the +compiler and included in your extension. Currently, this just means Windows +message text (:file:`.mc`) files and resource definition (:file:`.rc`) files for +Visual C++. These will be compiled to binary resource (:file:`.res`) files and +linked into the executable. + + +Preprocessor options +-------------------- + +Three optional arguments to :class:`Extension` will help if you need to specify +include directories to search or preprocessor macros to define/undefine: +``include_dirs``, ``define_macros``, and ``undef_macros``. + +For example, if your extension requires header files in the :file:`include` +directory under your distribution root, use the ``include_dirs`` option:: + + Extension('foo', ['foo.c'], include_dirs=['include']) + +You can specify absolute directories there; if you know that your extension will +only be built on Unix systems with X11R6 installed to :file:`/usr`, you can get +away with :: + + Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11']) + +You should avoid this sort of non-portable usage if you plan to distribute your +code: it's probably better to write C code like :: + + #include + +If you need to include header files from some other Python extension, you can +take advantage of the fact that header files are installed in a consistent way +by the Distutils :command:`install_header` command. For example, the Numerical +Python header files are installed (on a standard Unix installation) to +:file:`/usr/local/include/python1.5/Numerical`. (The exact location will differ +according to your platform and Python installation.) Since the Python include +directory---\ :file:`/usr/local/include/python1.5` in this case---is always +included in the search path when building Python extensions, the best approach +is to write C code like :: + + #include + +.. TODO check if it's d2.sysconfig or the new sysconfig module now + +If you must put the :file:`Numerical` include directory right into your header +search path, though, you can find that directory using the Distutils +:mod:`packaging.sysconfig` module:: + + from packaging.sysconfig import get_python_inc + incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical') + setup(..., + Extension(..., include_dirs=[incdir])) + +Even though this is quite portable---it will work on any Python installation, +regardless of platform---it's probably easier to just write your C code in the +sensible way. + +You can define and undefine preprocessor macros with the ``define_macros`` and +``undef_macros`` options. ``define_macros`` takes a list of ``(name, value)`` +tuples, where ``name`` is the name of the macro to define (a string) and +``value`` is its value: either a string or ``None``. (Defining a macro ``FOO`` +to ``None`` is the equivalent of a bare ``#define FOO`` in your C source: with +most compilers, this sets ``FOO`` to the string ``1``.) ``undef_macros`` is +just a list of macros to undefine. + +For example:: + + Extension(..., + define_macros=[('NDEBUG', '1'), + ('HAVE_STRFTIME', None)], + undef_macros=['HAVE_FOO', 'HAVE_BAR']) + +is the equivalent of having this at the top of every C source file:: + + #define NDEBUG 1 + #define HAVE_STRFTIME + #undef HAVE_FOO + #undef HAVE_BAR + + +Library options +--------------- + +You can also specify the libraries to link against when building your extension, +and the directories to search for those libraries. The ``libraries`` option is +a list of libraries to link against, ``library_dirs`` is a list of directories +to search for libraries at link-time, and ``runtime_library_dirs`` is a list of +directories to search for shared (dynamically loaded) libraries at run-time. + +For example, if you need to link against libraries known to be in the standard +library search path on target systems :: + + Extension(..., + libraries=['gdbm', 'readline']) + +If you need to link with libraries in a non-standard location, you'll have to +include the location in ``library_dirs``:: + + Extension(..., + library_dirs=['/usr/X11R6/lib'], + libraries=['X11', 'Xt']) + +(Again, this sort of non-portable construct should be avoided if you intend to +distribute your code.) + +.. XXX Should mention clib libraries here or somewhere else! + + +Other options +------------- + +There are still some other options which can be used to handle special cases. + +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. + +The :option:`extra_objects` option is a list of object files to be passed to the +linker. These files must not have extensions, as the default extension for the +compiler is used. + +:option:`extra_compile_args` and :option:`extra_link_args` can be used to +specify additional command-line options for the respective compiler and linker +command lines. + +:option:`export_symbols` is only useful on Windows. It can contain a list of +symbols (functions or variables) to be exported. This option is not needed when +building compiled extensions: Distutils will automatically add ``initmodule`` +to the list of exported symbols. + +The :option:`depends` option is a list of files that the extension depends on +(for example header files). The build command will call the compiler on the +sources to rebuild extension if any on this files has been modified since the +previous build. + +Relationships between Distributions and Packages +================================================ + +.. FIXME rewrite to update to PEP 345 (but without dist/release confusion) + +A distribution may relate to packages in three specific ways: + +#. It can require packages or modules. + +#. It can provide packages or modules. + +#. It can obsolete packages or modules. + +These relationships can be specified using keyword arguments to the +:func:`packaging.core.setup` function. + +Dependencies on other Python modules and packages can be specified by supplying +the *requires* keyword argument to :func:`setup`. The value must be a list of +strings. Each string specifies a package that is required, and optionally what +versions are sufficient. + +To specify that any version of a module or package is required, the string +should consist entirely of the module or package name. Examples include +``'mymodule'`` and ``'xml.parsers.expat'``. + +If specific versions are required, a sequence of qualifiers can be supplied in +parentheses. Each qualifier may consist of a comparison operator and a version +number. The accepted comparison operators are:: + + < > == + <= >= != + +These can be combined by using multiple qualifiers separated by commas (and +optional whitespace). In this case, all of the qualifiers must be matched; a +logical AND is used to combine the evaluations. + +Let's look at a bunch of examples: + ++-------------------------+----------------------------------------------+ +| Requires Expression | Explanation | ++=========================+==============================================+ +| ``==1.0`` | Only version ``1.0`` is compatible | ++-------------------------+----------------------------------------------+ +| ``>1.0, !=1.5.1, <2.0`` | Any version after ``1.0`` and before ``2.0`` | +| | is compatible, except ``1.5.1`` | ++-------------------------+----------------------------------------------+ + +Now that we can specify dependencies, we also need to be able to specify what we +provide that other distributions can require. This is done using the *provides* +keyword argument to :func:`setup`. The value for this keyword is a list of +strings, each of which names a Python module or package, and optionally +identifies the version. If the version is not specified, it is assumed to match +that of the distribution. + +Some examples: + ++---------------------+----------------------------------------------+ +| Provides Expression | Explanation | ++=====================+==============================================+ +| ``mypkg`` | Provide ``mypkg``, using the distribution | +| | version | ++---------------------+----------------------------------------------+ +| ``mypkg (1.1)`` | Provide ``mypkg`` version 1.1, regardless of | +| | the distribution version | ++---------------------+----------------------------------------------+ + +A package can declare that it obsoletes other packages using the *obsoletes* +keyword argument. The value for this is similar to that of the *requires* +keyword: a list of strings giving module or package specifiers. Each specifier +consists of a module or package name optionally followed by one or more version +qualifiers. Version qualifiers are given in parentheses after the module or +package name. + +The versions identified by the qualifiers are those that are obsoleted by the +distribution being described. If no qualifiers are given, all versions of the +named module or package are understood to be obsoleted. + +.. _packaging-installing-scripts: + +Installing Scripts +================== + +So far we have been dealing with pure and non-pure Python modules, which are +usually not run by themselves but imported by scripts. + +Scripts are files containing Python source code, intended to be started from the +command line. Scripts don't require Distutils to do anything very complicated. +The only clever feature is that if the first line of the script starts with +``#!`` and contains the word "python", the Distutils will adjust the first line +to refer to the current interpreter location. By default, it is replaced with +the current interpreter location. The :option:`--executable` (or :option:`-e`) +option will allow the interpreter path to be explicitly overridden. + +The :option:`scripts` option simply is a list of files to be handled in this +way. From the PyXML setup script:: + + setup(..., + scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']) + +All the scripts will also be added to the ``MANIFEST`` file if no template is +provided. See :ref:`packaging-manifest`. + +.. _packaging-installing-package-data: + +Installing Package Data +======================= + +Often, additional files need to be installed into a package. These files are +often data that's closely related to the package's implementation, or text files +containing documentation that might be of interest to programmers using the +package. These files are called :dfn:`package data`. + +Package data can be added to packages using the ``package_data`` keyword +argument to the :func:`setup` function. The value must be a mapping from +package name to a list of relative path names that should be copied into the +package. The paths are interpreted as relative to the directory containing the +package (information from the ``package_dir`` mapping is used if appropriate); +that is, the files are expected to be part of the package in the source +directories. They may contain glob patterns as well. + +The path names may contain directory portions; any necessary directories will be +created in the installation. + +For example, if a package should contain a subdirectory with several data files, +the files can be arranged like this in the source tree:: + + setup.py + src/ + mypkg/ + __init__.py + module.py + data/ + tables.dat + spoons.dat + forks.dat + +The corresponding call to :func:`setup` might be:: + + setup(..., + packages=['mypkg'], + package_dir={'mypkg': 'src/mypkg'}, + package_data={'mypkg': ['data/*.dat']}) + + +All the files that match ``package_data`` will be added to the ``MANIFEST`` +file if no template is provided. See :ref:`packaging-manifest`. + + +.. _packaging-additional-files: + +Installing Additional Files +=========================== + +The :option:`data_files` option can be used to specify additional files needed +by the module distribution: configuration files, message catalogs, data files, +anything which doesn't fit in the previous categories. + +:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the +following way:: + + setup(..., + data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), + ('config', ['cfg/data.cfg']), + ('/etc/init.d', ['init-script'])]) + +Note that you can specify the directory names where the data files will be +installed, but you cannot rename the data files themselves. + +Each (*directory*, *files*) pair in the sequence specifies the installation +directory and the files to install there. If *directory* is a relative path, it +is interpreted relative to the installation prefix (Python's ``sys.prefix`` for +pure-Python packages, ``sys.exec_prefix`` for packages that contain extension +modules). Each file name in *files* is interpreted relative to the +:file:`setup.py` script at the top of the package source distribution. No +directory information from *files* is used to determine the final location of +the installed file; only the name of the file is used. + +You can specify the :option:`data_files` options as a simple sequence of files +without specifying a target directory, but this is not recommended, and the +:command:`install_dist` command will print a warning in this case. To install data +files directly in the target directory, an empty string should be given as the +directory. + +All the files that match ``data_files`` will be added to the ``MANIFEST`` file +if no template is provided. See :ref:`packaging-manifest`. + + + +.. _packaging-metadata: + +Metadata reference +================== + +The setup script may include additional metadata beyond the name and version. +This table describes required and additional information: + +.. TODO synchronize with setupcfg; link to it (but don't remove it, it's a + useful summary) + ++----------------------+---------------------------+-----------------+--------+ +| Meta-Data | Description | Value | Notes | ++======================+===========================+=================+========+ +| ``name`` | name of the project | short string | \(1) | ++----------------------+---------------------------+-----------------+--------+ +| ``version`` | version of this release | short string | (1)(2) | ++----------------------+---------------------------+-----------------+--------+ +| ``author`` | project author's name | short string | \(3) | ++----------------------+---------------------------+-----------------+--------+ +| ``author_email`` | email address of the | email address | \(3) | +| | project author | | | ++----------------------+---------------------------+-----------------+--------+ +| ``maintainer`` | project maintainer's name | short string | \(3) | ++----------------------+---------------------------+-----------------+--------+ +| ``maintainer_email`` | email address of the | email address | \(3) | +| | project maintainer | | | ++----------------------+---------------------------+-----------------+--------+ +| ``home_page`` | home page for the project | URL | \(1) | ++----------------------+---------------------------+-----------------+--------+ +| ``summary`` | short description of the | short string | | +| | project | | | ++----------------------+---------------------------+-----------------+--------+ +| ``description`` | longer description of the | long string | \(5) | +| | project | | | ++----------------------+---------------------------+-----------------+--------+ +| ``download_url`` | location where the | URL | | +| | project may be downloaded | | | ++----------------------+---------------------------+-----------------+--------+ +| ``classifiers`` | a list of classifiers | list of strings | \(4) | ++----------------------+---------------------------+-----------------+--------+ +| ``platforms`` | a list of platforms | list of strings | | ++----------------------+---------------------------+-----------------+--------+ +| ``license`` | license for the release | short string | \(6) | ++----------------------+---------------------------+-----------------+--------+ + +Notes: + +(1) + These fields are required. + +(2) + It is recommended that versions take the form *major.minor[.patch[.sub]]*. + +(3) + Either the author or the maintainer must be identified. + +(4) + The list of classifiers is available from the `PyPI website + `_. See also :mod:`packaging.create`. + +(5) + The ``description`` field is used by PyPI when you are registering a + release, to build its PyPI page. + +(6) + The ``license`` field is a text indicating the license covering the + distribution where the license is not a selection from the "License" Trove + classifiers. See the ``Classifier`` field. Notice that + there's a ``licence`` distribution option which is deprecated but still + acts as an alias for ``license``. + +'short string' + A single line of text, not more than 200 characters. + +'long string' + Multiple lines of plain text in reStructuredText format (see + http://docutils.sf.net/). + +'list of strings' + See below. + +In Python 2.x, "string value" means a unicode object. If a byte string (str or +bytes) is given, it has to be valid ASCII. + +.. TODO move this section to the version document, keep a summary, add a link + +Encoding the version information is an art in itself. Python projects generally +adhere to the version format *major.minor[.patch][sub]*. The major number is 0 +for initial, experimental releases of software. It is incremented for releases +that represent major milestones in a project. The minor number is incremented +when important new features are added to the project. The patch number +increments when bug-fix releases are made. Additional trailing version +information is sometimes used to indicate sub-releases. These are +"a1,a2,...,aN" (for alpha releases, where functionality and API may change), +"b1,b2,...,bN" (for beta releases, which only fix bugs) and "pr1,pr2,...,prN" +(for final pre-release release testing). Some examples: + +0.1.0 + the first, experimental release of a project + +1.0.1a2 + the second alpha release of the first patch version of 1.0 + +:option:`classifiers` are specified in a Python list:: + + setup(..., + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: Web Environment', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Python Software Foundation License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Programming Language :: Python', + 'Topic :: Communications :: Email', + 'Topic :: Office/Business', + 'Topic :: Software Development :: Bug Tracking', + ]) + + +Debugging the setup script +========================== + +Sometimes things go wrong, and the setup script doesn't do what the developer +wants. + +Distutils catches any exceptions when running the setup script, and print a +simple error message before the script is terminated. The motivation for this +behaviour is to not confuse administrators who don't know much about Python and +are trying to install a project. If they get a big long traceback from deep +inside the guts of Distutils, they may think the project or the Python +installation is broken because they don't read all the way down to the bottom +and see that it's a permission problem. + +.. FIXME DISTUTILS_DEBUG is dead, document logging/warnings here + +On the other hand, this doesn't help the developer to find the cause of the +failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set +to anything except an empty string, and Packaging will now print detailed +information about what it is doing, and prints the full traceback in case an +exception occurs. diff --git a/Doc/packaging/sourcedist.rst b/Doc/packaging/sourcedist.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/sourcedist.rst @@ -0,0 +1,273 @@ +.. _packaging-source-dist: + +****************************** +Creating a Source Distribution +****************************** + +As shown in section :ref:`packaging-simple-example`, you use the :command:`sdist` command +to create a source distribution. In the simplest case, :: + + python setup.py sdist + +(assuming you haven't specified any :command:`sdist` options in the setup script +or config file), :command:`sdist` creates the archive of the default format for +the current platform. The default format is a gzip'ed tar file +(:file:`.tar.gz`) on Unix, and ZIP file on Windows. + +You can specify as many formats as you like using the :option:`--formats` +option, for example:: + + python setup.py sdist --formats=gztar,zip + +to create a gzipped tarball and a zip file. The available formats are: + ++-----------+-------------------------+---------+ +| Format | Description | Notes | ++===========+=========================+=========+ +| ``zip`` | zip file (:file:`.zip`) | (1),(3) | ++-----------+-------------------------+---------+ +| ``gztar`` | gzip'ed tar file | \(2) | +| | (:file:`.tar.gz`) | | ++-----------+-------------------------+---------+ +| ``bztar`` | bzip2'ed tar file | | +| | (:file:`.tar.bz2`) | | ++-----------+-------------------------+---------+ +| ``ztar`` | compressed tar file | \(4) | +| | (:file:`.tar.Z`) | | ++-----------+-------------------------+---------+ +| ``tar`` | tar file (:file:`.tar`) | | ++-----------+-------------------------+---------+ + +Notes: + +(1) + default on Windows + +(2) + default on Unix + +(3) + requires either external :program:`zip` utility or :mod:`zipfile` module (part + of the standard Python library since Python 1.6) + +(4) + requires the :program:`compress` program. Notice that this format is now + pending for deprecation and will be removed in the future versions of Python. + +When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or +``tar``) under Unix, you can specify the ``owner`` and ``group`` names +that will be set for each member of the archive. + +For example, if you want all files of the archive to be owned by root:: + + python setup.py sdist --owner=root --group=root + + +.. _packaging-manifest: + +Specifying the files to distribute +================================== + +If you don't supply an explicit list of files (or instructions on how to +generate one), the :command:`sdist` command puts a minimal default set into the +source distribution: + +* all Python source files implied by the :option:`py_modules` and + :option:`packages` options + +* all C source files mentioned in the :option:`ext_modules` or + :option:`libraries` options + +* scripts identified by the :option:`scripts` option + See :ref:`packaging-installing-scripts`. + +* anything that looks like a test script: :file:`test/test\*.py` (currently, the + Packaging don't do anything with test scripts except include them in source + distributions, but in the future there will be a standard for testing Python + module distributions) + +* the configuration file :file:`setup.cfg` + +* all files that matches the ``package_data`` metadata. + See :ref:`packaging-installing-package-data`. + +* all files that matches the ``data_files`` metadata. + See :ref:`packaging-additional-files`. + +Contrary to Distutils, :file:`README` (or :file:`README.txt`) and +:file:`setup.py` are not included by default. + +Sometimes this is enough, but usually you will want to specify additional files +to distribute. The typical way to do this is to write a *manifest template*, +called :file:`MANIFEST.in` by default. The manifest template is just a list of +instructions for how to generate your manifest file, :file:`MANIFEST`, which is +the exact list of files to include in your source distribution. The +:command:`sdist` command processes this template and generates a manifest based +on its instructions and what it finds in the filesystem. + +If you prefer to roll your own manifest file, the format is simple: one filename +per line, regular files (or symlinks to them) only. If you do supply your own +:file:`MANIFEST`, you must specify everything: the default set of files +described above does not apply in this case. + +:file:`MANIFEST` files start with a comment indicating they are generated. +Files without this comment are not overwritten or removed. + +See :ref:`packaging-manifest-template` section for a syntax reference. + + +.. _packaging-manifest-options: + +Manifest-related options +======================== + +The normal course of operations for the :command:`sdist` command is as follows: + +* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` + and create the manifest + +* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest + with just the default file set + +* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more + recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading + :file:`MANIFEST.in` + +* use the list of files now in :file:`MANIFEST` (either just generated or read + in) to create the source distribution archive(s) + +There are a couple of options that modify this behaviour. First, use the +:option:`--no-defaults` and :option:`--no-prune` to disable the standard +"include" and "exclude" sets. + +Second, you might just want to (re)generate the manifest, but not create a +source distribution:: + + python setup.py sdist --manifest-only + +:option:`-o` is a shortcut for :option:`--manifest-only`. + + +.. _packaging-manifest-template: + +The MANIFEST.in template +======================== + +A :file:`MANIFEST.in` file can be added in a project to define the list of +files to include in the distribution built by the :command:`sdist` command. + +When :command:`sdist` is run, it will look for the :file:`MANIFEST.in` file +and interpret it to generate the :file:`MANIFEST` file that contains the +list of files that will be included in the package. + +This mechanism can be used when the default list of files is not enough. +(See :ref:`packaging-manifest`). + +Principle +--------- + +The manifest template has one command per line, where each command specifies a +set of files to include or exclude from the source distribution. For an +example, let's look at the Packaging' own manifest template:: + + include *.txt + recursive-include examples *.txt *.py + prune examples/sample?/build + +The meanings should be fairly clear: include all files in the distribution root +matching :file:`\*.txt`, all files anywhere under the :file:`examples` directory +matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching +:file:`examples/sample?/build`. All of this is done *after* the standard +include set, so you can exclude files from the standard set with explicit +instructions in the manifest template. (Or, you can use the +:option:`--no-defaults` option to disable the standard set entirely.) + +The order of commands in the manifest template matters: initially, we have the +list of default files as described above, and each command in the template adds +to or removes from that list of files. Once we have fully processed the +manifest template, we remove files that should not be included in the source +distribution: + +* all files in the Packaging "build" tree (default :file:`build/`) + +* all files in directories named :file:`RCS`, :file:`CVS`, :file:`.svn`, + :file:`.hg`, :file:`.git`, :file:`.bzr` or :file:`_darcs` + +Now we have our complete list of files, which is written to the manifest for +future reference, and then used to build the source distribution archive(s). + +You can disable the default set of included files with the +:option:`--no-defaults` option, and you can disable the standard exclude set +with :option:`--no-prune`. + +Following the Packaging' own manifest template, let's trace how the +:command:`sdist` command builds the list of files to include in the Packaging +source distribution: + +#. include all Python source files in the :file:`packaging` and + :file:`packaging/command` subdirectories (because packages corresponding to + those two directories were mentioned in the :option:`packages` option in the + setup script---see section :ref:`packaging-setup-script`) + +#. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard + files) + +#. include :file:`test/test\*.py` (standard files) + +#. include :file:`\*.txt` in the distribution root (this will find + :file:`README.txt` a second time, but such redundancies are weeded out later) + +#. include anything matching :file:`\*.txt` or :file:`\*.py` in the sub-tree + under :file:`examples`, + +#. exclude all files in the sub-trees starting at directories matching + :file:`examples/sample?/build`\ ---this may exclude files included by the + previous two steps, so it's important that the ``prune`` command in the manifest + template comes after the ``recursive-include`` command + +#. exclude the entire :file:`build` tree, and any :file:`RCS`, :file:`CVS`, + :file:`.svn`, :file:`.hg`, :file:`.git`, :file:`.bzr` and :file:`_darcs` + directories + +Just like in the setup script, file and directory names in the manifest template +should always be slash-separated; the Packaging will take care of converting +them to the standard representation on your platform. That way, the manifest +template is portable across operating systems. + +Commands +-------- + +The manifest template commands are: + ++-------------------------------------------+-----------------------------------------------+ +| Command | Description | ++===========================================+===============================================+ +| :command:`include pat1 pat2 ...` | include all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`prune dir` | exclude all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ +| :command:`graft dir` | include all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ + +The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of +regular filename characters, ``?`` matches any single regular filename +character, and ``[range]`` matches any of the characters in *range* (e.g., +``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename +character" is platform-specific: on Unix it is anything except slash; on Windows +anything except backslash or colon. diff --git a/Doc/packaging/tutorial.rst b/Doc/packaging/tutorial.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/tutorial.rst @@ -0,0 +1,112 @@ +================== +Packaging tutorial +================== + +Welcome to the Packaging tutorial! We will learn how to use Packaging +to package your project. + +.. TODO merge with introduction.rst + + +Getting started +--------------- + +Packaging works with the *setup.cfg* file. It contains all the metadata for +your project, as defined in PEP 345, but also declare what your project +contains. + +Let's say you have a project called *CLVault* containing one package called +*clvault*, and a few scripts inside. You can use the *pysetup* script to create +a *setup.cfg* file for the project. The script will ask you a few questions:: + + $ mkdir CLVault + $ cd CLVault + $ pysetup create + Project name [CLVault]: + Current version number: 0.1 + Package description: + >Command-line utility to store and retrieve passwords + Author name: Tarek Ziade + Author e-mail address: tarek at ziade.org + Project Home Page: http://bitbucket.org/tarek/clvault + Do you want to add a package ? (y/n): y + Package name: clvault + Do you want to add a package ? (y/n): n + Do you want to set Trove classifiers? (y/n): y + Please select the project status: + + 1 - Planning + 2 - Pre-Alpha + 3 - Alpha + 4 - Beta + 5 - Production/Stable + 6 - Mature + 7 - Inactive + + Status: 3 + What license do you use: GPL + Matching licenses: + + 1) License :: OSI Approved :: GNU General Public License (GPL) + 2) License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) + + Type the number of the license you wish to use or ? to try again:: 1 + Do you want to set other trove identifiers (y/n) [n]: n + Wrote "setup.cfg". + + +A setup.cfg file is created, containing the metadata of your project and the +list of the packages it contains:: + + $ cat setup.cfg + [metadata] + name = CLVault + version = 0.1 + author = Tarek Ziade + author_email = tarek at ziade.org + description = Command-line utility to store and retrieve passwords + home_page = http://bitbucket.org/tarek/clvault + + classifier = Development Status :: 3 - Alpha + License :: OSI Approved :: GNU General Public License (GPL) + + [files] + packages = clvault + + +Our project will depend on the *keyring* project. Let's add it in the +[metadata] section:: + + [metadata] + ... + requires_dist = + keyring + + +Running commands +---------------- + +You can run useful commands on your project once the setup.cfg file is ready: + +- sdist: creates a source distribution +- register: register your project to PyPI +- upload: upload the distribution to PyPI +- install_dist: install it + +All commands are run using the run script:: + + $ pysetup run install_dist + $ pysetup run sdist + $ pysetup run upload + +If you want to push a source distribution of your project to PyPI, do:: + + $ pysetup run sdist register upload + + +Installing the project +---------------------- + +The project can be installed by manually running the packaging install command:: + + $ pysetup run install_dist diff --git a/Doc/packaging/uploading.rst b/Doc/packaging/uploading.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/uploading.rst @@ -0,0 +1,80 @@ +.. _packaging-package-upload: + +*************************************** +Uploading Packages to the Package Index +*************************************** + +The Python Package Index (PyPI) not only stores the package info, but also the +package data if the author of the package wishes to. The packaging command +:command:`upload` pushes the distribution files to PyPI. + +The command is invoked immediately after building one or more distribution +files. For example, the command :: + + python setup.py sdist bdist_wininst upload + +will cause the source distribution and the Windows installer to be uploaded to +PyPI. Note that these will be uploaded even if they are built using an earlier +invocation of :file:`setup.py`, but that only distributions named on the command +line for the invocation including the :command:`upload` command are uploaded. + +The :command:`upload` command uses the username, password, and repository URL +from the :file:`$HOME/.pypirc` file (see section :ref:`packaging-pypirc` for more on this +file). If a :command:`register` command was previously called in the same +command, and if the password was entered in the prompt, :command:`upload` will +reuse the entered password. This is useful if you do not want to store a clear +text password in the :file:`$HOME/.pypirc` file. + +You can specify another PyPI server with the :option:`--repository=*url*` +option:: + + python setup.py sdist bdist_wininst upload -r http://example.com/pypi + +See section :ref:`packaging-pypirc` for more on defining several servers. + +You can use the :option:`--sign` option to tell :command:`upload` to sign each +uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must +be available for execution on the system :envvar:`PATH`. You can also specify +which key to use for signing using the :option:`--identity=*name*` option. + +Other :command:`upload` options include :option:`--repository=` or +:option:`--repository=
` where *url* is the url of the server and +*section* the name of the section in :file:`$HOME/.pypirc`, and +:option:`--show-response` (which displays the full response text from the PyPI +server for help in debugging upload problems). + +PyPI package display +==================== + +The ``description`` field plays a special role at PyPI. It is used by +the server to display a home page for the registered package. + +If you use the `reStructuredText `_ +syntax for this field, PyPI will parse it and display an HTML output for +the package home page. + +The ``description`` field can be filled from a text file located in the +project:: + + from packaging.core import setup + + fp = open('README.txt') + try: + description = fp.read() + finally: + fp.close() + + setup(name='Packaging', + description=description) + +In that case, :file:`README.txt` is a regular reStructuredText text file located +in the root of the package besides :file:`setup.py`. + +To prevent registering broken reStructuredText content, you can use the +:program:`rst2html` program that is provided by the :mod:`docutils` package +and check the ``description`` from the command line:: + + $ python setup.py --description | rst2html.py > output.html + +:mod:`docutils` will display a warning if there's something wrong with your +syntax. diff --git a/Doc/tools/sphinxext/indexcontent.html b/Doc/tools/sphinxext/indexcontent.html --- a/Doc/tools/sphinxext/indexcontent.html +++ b/Doc/tools/sphinxext/indexcontent.html @@ -20,9 +20,9 @@ tutorial for C/C++ programmers

- - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 20:45:03 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 01 Jun 2011 20:45:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Kill_trailing_whitespace?= Message-ID: http://hg.python.org/cpython/rev/22f077f82e74 changeset: 70595:22f077f82e74 user: ?ric Araujo date: Wed Jun 01 20:44:40 2011 +0200 summary: Kill trailing whitespace files: Doc/install/pysetup-config.rst | 4 +- Doc/install/pysetup-servers.rst | 2 +- Doc/packaging/introduction.rst | 52 ++++++++++---------- Doc/packaging/setupscript.rst | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Doc/install/pysetup-config.rst b/Doc/install/pysetup-config.rst --- a/Doc/install/pysetup-config.rst +++ b/Doc/install/pysetup-config.rst @@ -11,8 +11,8 @@ Configuring indexes ------------------- -You can configure additional indexes in :file:`.pypirc` to be used for index-related -operations. By default, all configured index-servers and package-servers will be used +You can configure additional indexes in :file:`.pypirc` to be used for index-related +operations. By default, all configured index-servers and package-servers will be used in an additive fashion. To limit operations to specific indexes, use the :option:`--index` and :option:`--package-server options`:: diff --git a/Doc/install/pysetup-servers.rst b/Doc/install/pysetup-servers.rst --- a/Doc/install/pysetup-servers.rst +++ b/Doc/install/pysetup-servers.rst @@ -8,7 +8,7 @@ to PyPI indexes and mirrors. Package Servers are simple directory listings of Python distributions. Directories -can be served via HTTP or a local file system. This is useful when you want to +can be served via HTTP or a local file system. This is useful when you want to dump source distributions in a directory and not worry about the full index structure. Serving distributions from Apache diff --git a/Doc/packaging/introduction.rst b/Doc/packaging/introduction.rst --- a/Doc/packaging/introduction.rst +++ b/Doc/packaging/introduction.rst @@ -33,13 +33,13 @@ All of these tasks are covered in this document. -Not all module developers have access to multiple platforms, so one cannot +Not all module developers have access to multiple platforms, so one cannot expect them to create buildt distributions for every platform. To remedy this, it is hoped that intermediaries called *packagers* will arise to address this need. Packagers take source distributions released by module developers, -build them on one or more platforms and release the resulting built -distributions. Thus, users on a greater range of platforms will be able to -install the most popular Python modules in the most natural way for their +build them on one or more platforms and release the resulting built +distributions. Thus, users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their platform without having to run a setup script or compile a single line of code. @@ -69,14 +69,14 @@ arguments to the :func:`setup` function * those keyword arguments fall into two categories: package metadata (name, - version number, etc.) and information about what's in the package (a list + version number, etc.) and information about what's in the package (a list of pure Python modules in this case) * modules are specified by module name, not filename (the same will hold true for packages and extensions) -* it's recommended that you supply a little more metadata than we have in the - example. In particular your name, email address and a URL for the +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the project if appropriate (see section :ref:`packaging-setup-script` for an example) To create a source distribution for this module you would create a setup @@ -102,10 +102,10 @@ First, both developers and installers have the same basic user interface, i.e. the setup script. The difference is which Distutils *commands* they use: the :command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often used by installers (although some developers +:command:`install` is more often used by installers (although some developers will want to install their own code occasionally). -If you want to make things really easy for your users, you can create more +If you want to make things really easy for your users, you can create more than one built distributions for them. For instance, if you are running on a Windows machine and want to make things easy for other Windows users, you can create an executable installer (the most appropriate type of built distribution @@ -125,18 +125,18 @@ General Python terminology ========================== -If you're reading this document, you probably have a good idea of what Python -modules, extensions and so forth are. Nevertheless, just to be sure that +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that everyone is on the same page, here's a quick overview of Python terms: module - The basic unit of code reusability in Python: a block of code imported by - some other code. Three types of modules are important to us here: pure + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure Python modules, extension modules and packages. pure Python module A module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes referred to as a "pure module." extension module @@ -148,18 +148,18 @@ currently Distutils only handles C/C++ extensions for Python. package - A module that contains other modules, typically contained in a directory of - the filesystem and distinguished from other directories by the presence of a + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a file :file:`__init__.py`. root package - The root of the hierarchy of packages. (This isn't really a package, - since it doesn't have an :file:`__init__.py` file. But... we have to - call it something, right?) The vast majority of the standard library is - in the root package, as are many small standalone third-party modules that - don't belong to a larger module collection. Unlike regular packages, - modules in the root package can be found in many directories: in fact, - every directory listed in ``sys.path`` contributes modules to the root + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root package. @@ -175,8 +175,8 @@ A collection of Python modules distributed together as a single downloadable resource and meant to be installed all as one. Examples of some well-known module distributions are NumPy, SciPy, PIL (the Python Imaging - Library) or mxBase. (Module distributions would be called a *package*, - except that term is already taken in the Python context: a single module + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module distribution may contain zero, one, or many Python packages.) pure module distribution @@ -189,5 +189,5 @@ distribution root The top-level directory of your source tree (or source distribution). The - directory where :file:`setup.py` exists. Generally :file:`setup.py` will + directory where :file:`setup.py` exists. Generally :file:`setup.py` will be run from this directory. diff --git a/Doc/packaging/setupscript.rst b/Doc/packaging/setupscript.rst --- a/Doc/packaging/setupscript.rst +++ b/Doc/packaging/setupscript.rst @@ -9,7 +9,7 @@ to describe your module distribution to Distutils, so that the various commands that operate on your modules do the right thing. As we saw in section :ref:`packaging-simple-example`, the setup script consists mainly of a -call to :func:`setup` where the most information is supplied as +call to :func:`setup` where the most information is supplied as keyword arguments to :func:`setup`. Here's a slightly more involved example, which we'll follow for the next couple -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 1 20:54:29 2011 From: python-checkins at python.org (ezio.melotti) Date: Wed, 1 Jun 2011 20:54:29 +0200 (CEST) Subject: [Python-checkins] r88849 - tracker/instances/python-dev/html/issue.item.js Message-ID: <3Ql17n4fVHz7LlG@mail.python.org> Author: ezio.melotti Date: Wed Jun 1 20:54:29 2011 New Revision: 88849 Log: Limit the scroll to the y axis. Modified: tracker/instances/python-dev/html/issue.item.js Modified: tracker/instances/python-dev/html/issue.item.js ============================================================================== --- tracker/instances/python-dev/html/issue.item.js (original) +++ tracker/instances/python-dev/html/issue.item.js Wed Jun 1 20:54:29 2011 @@ -55,7 +55,7 @@ if ((event.keyCode == 35) && (node != 'TEXTAREA') && (node != 'INPUT') && (node != 'SELECT')) { // jump at the last message and restore the usual behavior - window.scrollTo(offset.left, offset.top); + window.scrollTo(0, offset.top); $(document).unbind('keydown') return false; } From python-checkins at python.org Wed Jun 1 23:57:23 2011 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 01 Jun 2011 23:57:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Link_to_suggest?= =?utf8?q?ions_for_how_to_use_super=28=29=2E?= Message-ID: http://hg.python.org/cpython/rev/418d2d3117ca changeset: 70596:418d2d3117ca branch: 2.7 parent: 70580:3e445ceee4f5 user: Raymond Hettinger date: Wed Jun 01 14:57:13 2011 -0700 summary: Link to suggestions for how to use super(). files: Doc/library/functions.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1335,6 +1335,10 @@ argument form specifies the arguments exactly and makes the appropriate references. + For practical suggestions on how to design cooperative classes using + :func:`super`, see `guide to using super() + `_. + .. versionadded:: 2.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 00:50:42 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 02 Jun 2011 00:50:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Multiple_clean-?= =?utf8?q?ups_to_the_docs_for_builtin_functions=2E?= Message-ID: http://hg.python.org/cpython/rev/cc678de70d17 changeset: 70597:cc678de70d17 branch: 2.7 user: Raymond Hettinger date: Wed Jun 01 15:50:34 2011 -0700 summary: Multiple clean-ups to the docs for builtin functions. * Use concrete example for dir() and eliminate the distracting doctest directives. * Add a pure python equivalent for enumerate() * Modify the enumerate() example to demonstrate the start argument * Remove incorrect reference the *iterable* in the enumerate() docs. * Downgrade the comments on input() from a warning to a note. * Fix the iter() example to use the empty string as the terminating condition for file.readline(). Also, the old example was broken because readline() results include a newline, so 'STOP\n' would have been the correct terminating condition. Even with that fix, the STOP example was fragile and would have lead to infinite loops with malformed inputs. * Do not refer to classmethod as being "more advanced" than staticmethod. files: Doc/library/functions.rst | 62 ++++++++++++++------------ 1 files changed, 34 insertions(+), 28 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -298,19 +298,19 @@ The resulting list is sorted alphabetically. For example: >>> import struct - >>> dir() # doctest: +SKIP + >>> dir() # show the names in the module namespace ['__builtins__', '__doc__', '__name__', 'struct'] - >>> dir(struct) # doctest: +NORMALIZE_WHITESPACE + >>> dir(struct) # show the names in the struct module ['Struct', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from'] - >>> class Foo(object): - ... def __dir__(self): - ... return ["kan", "ga", "roo"] - ... - >>> f = Foo() + >>> class Shape(object): + def __dir__(self): + return ['area', 'perimter', 'location'] + + >>> f = Shape() >>> dir(f) - ['ga', 'kan', 'roo'] + ['area', 'perimter', 'location'] .. note:: @@ -342,16 +342,22 @@ :term:`iterator`, or some other object which supports iteration. The :meth:`!next` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the - corresponding value obtained from iterating over *iterable*. - :func:`enumerate` is useful for obtaining an indexed series: ``(0, seq[0])``, - ``(1, seq[1])``, ``(2, seq[2])``, .... For example: + corresponding value obtained from iterating over *sequence*:: - >>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): - ... print i, season - 0 Spring - 1 Summer - 2 Fall - 3 Winter + >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): + print i, season + 1 Spring + 2 Summer + 3 Fall + 4 Winter + + Equivalent to:: + + def enumerate(sequence, start=0): + n = start + for elem in sequence: + yield n, elem + n += 1 .. versionadded:: 2.3 .. versionadded:: 2.6 @@ -586,13 +592,12 @@ Equivalent to ``eval(raw_input(prompt))``. - .. warning:: + .. note:: - This function is not safe from user errors! It expects a valid Python - expression as input; if the input is not syntactically valid, a - :exc:`SyntaxError` will be raised. Other exceptions may be raised if there is an - error during evaluation. (On the other hand, sometimes this is exactly what you - need when writing a quick script for expert use.) + This function does not catch user errors. It expects a valid Python + expression as input. If the input is not syntactically valid, a + :exc:`SyntaxError` will be raised. Other exceptions may be raised if there + is an error during evaluation. If the :mod:`readline` module was loaded, then :func:`input` will use it to provide elaborate line editing and history features. @@ -660,10 +665,10 @@ One useful application of the second form of :func:`iter` is to read lines of a file until a certain line is reached. The following example reads a file - until ``"STOP"`` is reached: :: + until the :meth:`readline` method returns an empty string:: - with open("mydata.txt") as fp: - for line in iter(fp.readline, "STOP"): + with open('mydata.txt') as fp: + for line in iter(fp.readline, ''): process_line(line) .. versionadded:: 2.2 @@ -1241,8 +1246,9 @@ It can be called either on the class (such as ``C.f()``) or on an instance (such as ``C().f()``). The instance is ignored except for its class. - Static methods in Python are similar to those found in Java or C++. For a more - advanced concept, see :func:`classmethod` in this section. + Static methods in Python are similar to those found in Java or C++. Also see + :func:`classmethod` for a variant that is useful for creating alternate + class constructors. For more information on static methods, consult the documentation on the standard type hierarchy in :ref:`types`. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 01:01:30 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 02 Jun 2011 01:01:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Cleanup_example?= Message-ID: http://hg.python.org/cpython/rev/bbaf419e7d0a changeset: 70598:bbaf419e7d0a branch: 2.7 user: Raymond Hettinger date: Wed Jun 01 16:01:21 2011 -0700 summary: Cleanup example files: Doc/library/functions.rst | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -306,11 +306,10 @@ 'unpack', 'unpack_from'] >>> class Shape(object): def __dir__(self): - return ['area', 'perimter', 'location'] - - >>> f = Shape() - >>> dir(f) - ['area', 'perimter', 'location'] + return ['area', 'perimeter', 'location'] + >>> s = Shape() + >>> dir(s) + ['area', 'perimeter', 'location'] .. note:: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 01:18:09 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 02 Jun 2011 01:18:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Forward_port_do?= =?utf8?q?c_updates_for_builtin_functions=2E?= Message-ID: http://hg.python.org/cpython/rev/eebe41341ab9 changeset: 70599:eebe41341ab9 branch: 3.2 parent: 70589:5e75517696d4 user: Raymond Hettinger date: Wed Jun 01 16:17:23 2011 -0700 summary: Forward port doc updates for builtin functions. files: Doc/library/functions.rst | 54 ++++++++++++++++----------- 1 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -290,19 +290,18 @@ The resulting list is sorted alphabetically. For example: >>> import struct - >>> dir() # doctest: +SKIP + >>> dir() # show the names in the module namespace ['__builtins__', '__doc__', '__name__', 'struct'] - >>> dir(struct) # doctest: +NORMALIZE_WHITESPACE + >>> dir(struct) # show the names in the struct module ['Struct', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from'] - >>> class Foo: - ... def __dir__(self): - ... return ["kan", "ga", "roo"] - ... - >>> f = Foo() - >>> dir(f) - ['ga', 'kan', 'roo'] + >>> class Shape(object): + def __dir__(self): + return ['area', 'perimeter', 'location'] + >>> s = Shape() + >>> dir(s) + ['area', 'perimeter', 'location'] .. note:: @@ -333,15 +332,21 @@ :meth:`__next__` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the corresponding value obtained from iterating over *iterable*. - :func:`enumerate` is useful for obtaining an indexed series: ``(0, seq[0])``, - ``(1, seq[1])``, ``(2, seq[2])``, .... For example: - >>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): - ... print(i, season) - 0 Spring - 1 Summer - 2 Fall - 3 Winter + >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): + print(i, season) + 1 Spring + 2 Summer + 3 Fall + 4 Winter + + Equivalent to:: + + def enumerate(sequence, start=0): + n = start + for elem in sequence: + yield n, elem + n += 1 .. function:: eval(expression, globals=None, locals=None) @@ -652,10 +657,10 @@ One useful application of the second form of :func:`iter` is to read lines of a file until a certain line is reached. The following example reads a file - until ``"STOP"`` is reached: :: + until the :meth:`readline` method returns an empty string:: - with open("mydata.txt") as fp: - for line in iter(fp.readline, "STOP"): + with open('mydata.txt') as fp: + for line in iter(fp.readline, ''): process_line(line) @@ -1169,8 +1174,9 @@ It can be called either on the class (such as ``C.f()``) or on an instance (such as ``C().f()``). The instance is ignored except for its class. - Static methods in Python are similar to those found in Java or C++. For a more - advanced concept, see :func:`classmethod` in this section. + Static methods in Python are similar to those found in Java or C++. Also see + :func:`classmethod` for a variant that is useful for creating alternate class + constructors. For more information on static methods, consult the documentation on the standard type hierarchy in :ref:`types`. @@ -1270,6 +1276,10 @@ references. The zero argument form automatically searches the stack frame for the class (``__class__``) and the first argument. + For practical suggestions on how to design cooperative classes using + :func:`super`, see `guide to using super() + `_. + .. function:: tuple([iterable]) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 01:18:10 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 02 Jun 2011 01:18:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge?= Message-ID: http://hg.python.org/cpython/rev/bd3447481d70 changeset: 70600:bd3447481d70 parent: 70595:22f077f82e74 parent: 70599:eebe41341ab9 user: Raymond Hettinger date: Wed Jun 01 16:18:00 2011 -0700 summary: merge files: Doc/library/functions.rst | 54 ++++++++++++++++----------- 1 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -290,19 +290,18 @@ The resulting list is sorted alphabetically. For example: >>> import struct - >>> dir() # doctest: +SKIP + >>> dir() # show the names in the module namespace ['__builtins__', '__doc__', '__name__', 'struct'] - >>> dir(struct) # doctest: +NORMALIZE_WHITESPACE + >>> dir(struct) # show the names in the struct module ['Struct', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from'] - >>> class Foo: - ... def __dir__(self): - ... return ["kan", "ga", "roo"] - ... - >>> f = Foo() - >>> dir(f) - ['ga', 'kan', 'roo'] + >>> class Shape(object): + def __dir__(self): + return ['area', 'perimeter', 'location'] + >>> s = Shape() + >>> dir(s) + ['area', 'perimeter', 'location'] .. note:: @@ -333,15 +332,21 @@ :meth:`__next__` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the corresponding value obtained from iterating over *iterable*. - :func:`enumerate` is useful for obtaining an indexed series: ``(0, seq[0])``, - ``(1, seq[1])``, ``(2, seq[2])``, .... For example: - >>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): - ... print(i, season) - 0 Spring - 1 Summer - 2 Fall - 3 Winter + >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): + print(i, season) + 1 Spring + 2 Summer + 3 Fall + 4 Winter + + Equivalent to:: + + def enumerate(sequence, start=0): + n = start + for elem in sequence: + yield n, elem + n += 1 .. function:: eval(expression, globals=None, locals=None) @@ -652,10 +657,10 @@ One useful application of the second form of :func:`iter` is to read lines of a file until a certain line is reached. The following example reads a file - until ``"STOP"`` is reached: :: + until the :meth:`readline` method returns an empty string:: - with open("mydata.txt") as fp: - for line in iter(fp.readline, "STOP"): + with open('mydata.txt') as fp: + for line in iter(fp.readline, ''): process_line(line) @@ -1169,8 +1174,9 @@ It can be called either on the class (such as ``C.f()``) or on an instance (such as ``C().f()``). The instance is ignored except for its class. - Static methods in Python are similar to those found in Java or C++. For a more - advanced concept, see :func:`classmethod` in this section. + Static methods in Python are similar to those found in Java or C++. Also see + :func:`classmethod` for a variant that is useful for creating alternate class + constructors. For more information on static methods, consult the documentation on the standard type hierarchy in :ref:`types`. @@ -1270,6 +1276,10 @@ references. The zero argument form automatically searches the stack frame for the class (``__class__``) and the first argument. + For practical suggestions on how to design cooperative classes using + :func:`super`, see `guide to using super() + `_. + .. function:: tuple([iterable]) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 03:32:41 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 02 Jun 2011 03:32:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_sys=2Echeckinte?= =?utf8?q?rval=28=29_now_refreshes_the_current_countdown_ticker=2E?= Message-ID: http://hg.python.org/cpython/rev/4af63c08f68a changeset: 70601:4af63c08f68a branch: 2.7 parent: 70598:bbaf419e7d0a user: Raymond Hettinger date: Wed Jun 01 18:21:42 2011 -0700 summary: sys.checkinterval() now refreshes the current countdown ticker. files: Misc/NEWS | 7 +++++++ Python/sysmodule.c | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,13 @@ Library ------- +- sys.setcheckinterval() now updates the current ticker count as well as updating + the check interval, so if the user decreases the check interval, the ticker + doesn't have to wind down to zero from the old starting point before the new + interval takes effect. And if the user increases the interval, it makes sure + the new limit takes effect right away rather have an early task switch before + recognizing the new interval. + - Issue #12085: Fix an attribute error in subprocess.Popen destructor if the constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. diff --git a/Python/sysmodule.c b/Python/sysmodule.c --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -466,6 +466,7 @@ { if (!PyArg_ParseTuple(args, "i:setcheckinterval", &_Py_CheckInterval)) return NULL; + _Py_Ticker = _Py_CheckInterval; Py_INCREF(Py_None); return Py_None; } -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Thu Jun 2 05:07:24 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 02 Jun 2011 05:07:24 +0200 Subject: [Python-checkins] Daily reference leaks (bd3447481d70): sum=343 Message-ID: results for bd3447481d70 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 test_pyexpat leaked [0, 0, -56] references, sum=-56 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogiRUN7N', '-x'] From python-checkins at python.org Thu Jun 2 11:28:17 2011 From: python-checkins at python.org (tarek.ziade) Date: Thu, 02 Jun 2011 11:28:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_this_documentation_is_now_h?= =?utf8?q?andled_by_all_the_new_packaging_contributors?= Message-ID: http://hg.python.org/cpython/rev/3dbf4c9b3ed4 changeset: 70602:3dbf4c9b3ed4 parent: 70600:bd3447481d70 user: Tarek Ziade date: Thu Jun 02 11:28:07 2011 +0200 summary: this documentation is now handled by all the new packaging contributors files: Doc/packaging/index.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/packaging/index.rst b/Doc/packaging/index.rst --- a/Doc/packaging/index.rst +++ b/Doc/packaging/index.rst @@ -4,7 +4,7 @@ Distributing Python Projects ############################## -:Authors: Greg Ward, Anthony Baxter and Packaging contributors +:Authors: The Fellowship of The Packaging :Email: distutils-sig at python.org :Release: |version| :Date: |today| -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 12:00:50 2011 From: python-checkins at python.org (tarek.ziade) Date: Thu, 02 Jun 2011 12:00:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_added_the_generate-setup_ac?= =?utf8?q?tion?= Message-ID: http://hg.python.org/cpython/rev/b95096303ed2 changeset: 70603:b95096303ed2 user: Tarek Ziade date: Thu Jun 02 12:00:44 2011 +0200 summary: added the generate-setup action files: Lib/packaging/run.py | 18 +++++++++++++++++- Lib/packaging/util.py | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -9,7 +9,7 @@ from packaging import logger from packaging.dist import Distribution -from packaging.util import _is_archive_file +from packaging.util import _is_archive_file, generate_setup_py from packaging.command import get_command_class, STANDARD_COMMANDS from packaging.install import install, install_local_project, remove from packaging.database import get_distribution, get_distributions @@ -38,6 +38,14 @@ Create a new Python package. """ +generate_usage = """\ +Usage: pysetup generate-setup + or: pysetup generate-setup --help + +Generates a setup.py script for backward-compatibility purposes. +""" + + graph_usage = """\ Usage: pysetup graph dist or: pysetup graph --help @@ -204,6 +212,13 @@ return main() + at action_help(generate_usage) +def _generate(distpatcher, args, **kw): + generate_setup_py() + print('The setup.py was generated') + + + @action_help(graph_usage) def _graph(dispatcher, args, **kw): name = args[1] @@ -381,6 +396,7 @@ ('list', 'Search for local projects', _list), ('graph', 'Display a graph', _graph), ('create', 'Create a Project', _create), + ('generate-setup', 'Generates a backward-comptatible setup.py', _generate) ] diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1087,7 +1087,7 @@ Raises a PackagingFileError when a setup.py already exists. """ if os.path.exists("setup.py"): - raise PackagingFileError("a setup.py file alreadyexists") + raise PackagingFileError("a setup.py file already exists") with open("setup.py", "w", encoding='utf-8') as fp: fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)}) -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Thu Jun 2 15:56:07 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 2 Jun 2011 23:56:07 +1000 Subject: [Python-checkins] cpython: The compiler class for EMX was removed In-Reply-To: References: Message-ID: On Thu, Jun 2, 2011 at 3:47 AM, eric.araujo wrote: > http://hg.python.org/cpython/rev/c3f8991cd74d > changeset: ? 70587:c3f8991cd74d > user: ? ? ? ??ric Araujo > date: ? ? ? ?Wed Jun 01 15:20:44 2011 +0200 > summary: > ?The compiler class for EMX was removed This is the kind of checkin comment where the phrasing is a little confusing. It could mean either "was removed by mistake and has now been restored" or else "is no longer supported and has been removed". (Checking the diff resolves the ambiguity in favour of the latter interpretation, but not all diffs are as simple as this one). It's worth trying to make the final state of the source tree explicit in the checkin message (no need to edit the history, just a note for future reference). Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Thu Jun 2 16:43:47 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 02 Jun 2011 16:43:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Make_packaging=2Etests=2Esu?= =?utf8?q?pport=2ELoggingCatcher=2Eget=5Flogs_flush_the_log_handler=2E?= Message-ID: http://hg.python.org/cpython/rev/c25c403e54cb changeset: 70604:c25c403e54cb parent: 70595:22f077f82e74 user: ?ric Araujo date: Thu Jun 02 14:53:59 2011 +0200 summary: Make packaging.tests.support.LoggingCatcher.get_logs flush the log handler. This removes the need to call flush manually in each test, except when testing code that creates warning without checking them. files: Lib/packaging/tests/support.py | 20 +++++++--- Lib/packaging/tests/test_command_check.py | 11 +++-- Lib/packaging/tests/test_manifest.py | 3 - 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py --- a/Lib/packaging/tests/support.py +++ b/Lib/packaging/tests/support.py @@ -90,17 +90,23 @@ def get_logs(self, *levels): """Return all log messages with level in *levels*. - Without explicit levels given, returns all messages. - *levels* defaults to all levels. For log calls with arguments (i.e. - logger.info('bla bla %s', arg)), the messages - Returns a list. + Without explicit levels given, returns all messages. *levels* defaults + to all levels. For log calls with arguments (i.e. + logger.info('bla bla %r', arg)), the messages will be formatted before + being returned (e.g. "bla bla 'thing'"). + + Returns a list. Automatically flushes the loghandler after being + called. Example: self.get_logs(logging.WARN, logging.DEBUG). """ if not levels: - return [log.getMessage() for log in self.loghandler.buffer] - return [log.getMessage() for log in self.loghandler.buffer - if log.levelno in levels] + messages = [log.getMessage() for log in self.loghandler.buffer] + else: + messages = [log.getMessage() for log in self.loghandler.buffer + if log.levelno in levels] + self.loghandler.flush() + return messages class TempdirManager: diff --git a/Lib/packaging/tests/test_command_check.py b/Lib/packaging/tests/test_command_check.py --- a/Lib/packaging/tests/test_command_check.py +++ b/Lib/packaging/tests/test_command_check.py @@ -36,7 +36,6 @@ # now let's add the required fields # and run it again, to make sure we don't get # any warning anymore - self.loghandler.flush() metadata = {'home_page': 'xxx', 'author': 'xxx', 'author_email': 'xxx', 'name': 'xxx', 'version': '4.2', @@ -50,8 +49,10 @@ self.assertRaises(PackagingSetupError, self._run, {'name': 'xxx', 'version': 'xxx'}, **{'strict': 1}) + # clear warnings from the previous calls + self.loghandler.flush() + # and of course, no error when all metadata fields are present - self.loghandler.flush() cmd = self._run(metadata, strict=True) self.assertEqual([], self.get_logs(logging.WARNING)) @@ -70,7 +71,6 @@ 'name': 'xxx', 'version': '4.2', 'requires_python': '2.4', } - self.loghandler.flush() cmd = self._run(metadata) self.assertEqual([], self.get_logs(logging.WARNING)) @@ -85,9 +85,11 @@ self.assertRaises(PackagingSetupError, self._run, metadata, **{'strict': 1}) + # clear warnings from the previous calls + self.loghandler.flush() + # now with correct version format again metadata['version'] = '4.2' - self.loghandler.flush() cmd = self._run(metadata, strict=True) self.assertEqual([], self.get_logs(logging.WARNING)) @@ -100,7 +102,6 @@ cmd.check_restructuredtext() self.assertEqual(len(self.get_logs(logging.WARNING)), 1) - self.loghandler.flush() pkg_info, dist = self.create_dist(description='title\n=====\n\ntest') cmd = check(dist) cmd.check_restructuredtext() diff --git a/Lib/packaging/tests/test_manifest.py b/Lib/packaging/tests/test_manifest.py --- a/Lib/packaging/tests/test_manifest.py +++ b/Lib/packaging/tests/test_manifest.py @@ -50,9 +50,6 @@ for warning in warnings: self.assertIn('no files found matching', warning) - # reset logs for the next assert - self.loghandler.flush() - # manifest also accepts file-like objects with open(MANIFEST) as f: manifest.read_template(f) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 16:43:47 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 02 Jun 2011 16:43:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_format_of_warnings_from?= =?utf8?q?_the_packaging_check_command?= Message-ID: http://hg.python.org/cpython/rev/31727f819caf changeset: 70605:31727f819caf user: ?ric Araujo date: Thu Jun 02 14:54:44 2011 +0200 summary: Fix format of warnings from the packaging check command files: Lib/packaging/command/check.py | 2 +- Lib/packaging/tests/test_command_check.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/command/check.py b/Lib/packaging/command/check.py --- a/Lib/packaging/command/check.py +++ b/Lib/packaging/command/check.py @@ -32,7 +32,7 @@ # XXX we could use a special handler for this, but would need to test # if it works even if the logger has a too high level self._warnings.append((msg, args)) - return logger.warning(self.get_command_name() + msg, *args) + return logger.warning('%s: %s' % (self.get_command_name(), msg), *args) def run(self): """Runs the command.""" diff --git a/Lib/packaging/tests/test_command_check.py b/Lib/packaging/tests/test_command_check.py --- a/Lib/packaging/tests/test_command_check.py +++ b/Lib/packaging/tests/test_command_check.py @@ -124,6 +124,17 @@ cmd.check_hooks_resolvable() self.assertEqual(len(self.get_logs(logging.WARNING)), 1) + def test_warn(self): + _, dist = self.create_dist() + cmd = check(dist) + self.assertEqual([], self.get_logs()) + cmd.warn('hello') + self.assertEqual(['check: hello'], self.get_logs()) + cmd.warn('hello %s', 'world') + self.assertEqual(['check: hello world'], self.get_logs()) + cmd.warn('hello %s %s', 'beautiful', 'world') + self.assertEqual(['check: hello beautiful world'], self.get_logs()) + def test_suite(): return unittest.makeSuite(CheckTestCase) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 2 16:43:48 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 02 Jun 2011 16:43:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging_doc=3A_Add_missin?= =?utf8?q?g_index_file=2C_improve_main_page_description=2E?= Message-ID: http://hg.python.org/cpython/rev/4c6d8ecef78d changeset: 70606:4c6d8ecef78d user: ?ric Araujo date: Thu Jun 02 15:45:25 2011 +0200 summary: Packaging doc: Add missing index file, improve main page description. Also promote notices from distutils doc to deprecation boxes. files: Doc/distutils/index.rst | 10 +- Doc/install/index.rst | 56 +++++++++++++++ Doc/library/distutils.rst | 15 ++- Doc/tools/sphinxext/indexcontent.html | 4 +- 4 files changed, 71 insertions(+), 14 deletions(-) diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -14,6 +14,10 @@ make Python modules and extensions easily available to a wider audience with very little overhead for build/release/install mechanics. +.. deprecated:: 3.3 + :mod:`packaging` replaces Distutils. See :ref:`packaging-index` and + :ref:`packaging-install-index`. + .. toctree:: :maxdepth: 2 :numbered: @@ -36,9 +40,3 @@ .. toctree:: install.rst - - -.. seealso:: - - :ref:`packaging-index` and :ref:`packaging-install-index` - Documentation of Packaging, the new version of Distutils. diff --git a/Doc/install/index.rst b/Doc/install/index.rst new file mode 100644 --- /dev/null +++ b/Doc/install/index.rst @@ -0,0 +1,56 @@ +.. _packaging-install-index: + +****************************** + Installing Python Projects +****************************** + +:Author: Greg Ward and Packaging contributors +:Release: |version| +:Date: |today| + +.. TODO: Fill in XXX comments + +.. The audience for this document includes people who don't know anything + about Python and aren't about to learn the language just in order to + install and maintain it for their users, i.e. system administrators. + Thus, I have to be sure to explain the basics at some point: + sys.path and PYTHONPATH at least. Should probably give pointers to + other docs on "import site", PYTHONSTARTUP, PYTHONHOME, etc. + + Finally, it might be useful to include all the material from my "Care + and Feeding of a Python Installation" talk in here somewhere. Yow! + +.. topic:: Abstract + + This document describes Packaging from the end-user's point of view: it + explains how to extend the functionality of a standard Python installation by + building and installing third-party Python modules and applications. + + +This guide is split into a simple overview followed by a longer presentation of +the :program:`pysetup` script, the Python package management tool used to +build, distribute, search for, install, remove and list Python distributions. + +.. TODO integrate install and pysetup instead of duplicating + +.. toctree:: + :maxdepth: 2 + :numbered: + + install + pysetup + pysetup-config + pysetup-servers + + +.. seealso:: + + :ref:`packaging-index` + The manual for developers of Python projects who want to package and + distribute them. This describes how to use :mod:`packaging` to make + projects easily found and added to an existing Python installation. + + :mod:`packaging` + A library reference for developers of packaging tools wanting to use + standalone building blocks like :mod:`~packaging.version` or + :mod:`~packaging.metadata`, or extend Packaging itself. diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst --- a/Doc/library/distutils.rst +++ b/Doc/library/distutils.rst @@ -12,21 +12,24 @@ 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C. -This package is discussed in two separate chapters: +.. deprecated:: 3.3 + :mod:`packaging` replaces Distutils. See :ref:`packaging-index` and + :ref:`packaging-install-index`. +User documentation and API reference are provided in another document: + .. seealso:: :ref:`distutils-index` The manual for developers and packagers of Python modules. This describes how to prepare :mod:`distutils`\ -based packages so that they may be - easily installed into an existing Python installation. + easily installed into an existing Python installation. If also contains + instructions for end-users wanting to install a distutils-based package, + :ref:`install-index`. - :ref:`install-index` - An "administrators" manual which includes information on installing - modules into an existing Python installation. You do not need to be a - Python programmer to read this manual. +.. trick to silence a Sphinx warning .. toctree:: :hidden: diff --git a/Doc/tools/sphinxext/indexcontent.html b/Doc/tools/sphinxext/indexcontent.html --- a/Doc/tools/sphinxext/indexcontent.html +++ b/Doc/tools/sphinxext/indexcontent.html @@ -21,9 +21,9 @@ + finding and installing modules and applications

+ packaging and distributing modules and applications

+ finding and installing modules and applications

+ packaging and distributing modules and applications

- -where you can supply any directory you like for the :option:`--home` option. On -Unix, lazy typists can just type a tilde (``~``); the :command:`install` command -will expand this to your home directory:: - - python setup.py install --home=~ - -The :option:`--home` option defines the installation base directory. Files are -installed to the following directories under the installation base as follows: - -+------------------------------+---------------------------+-----------------------------+ -| Type of file | Installation Directory | Override option | -+==============================+===========================+=============================+ -| pure module distribution | :file:`{home}/lib/python` | :option:`--install-purelib` | -+------------------------------+---------------------------+-----------------------------+ -| non-pure module distribution | :file:`{home}/lib/python` | :option:`--install-platlib` | -+------------------------------+---------------------------+-----------------------------+ -| scripts | :file:`{home}/bin` | :option:`--install-scripts` | -+------------------------------+---------------------------+-----------------------------+ -| data | :file:`{home}/share` | :option:`--install-data` | -+------------------------------+---------------------------+-----------------------------+ - - -.. _inst-alt-install-home: - -Alternate installation: Unix (the prefix scheme) ------------------------------------------------- - -The "prefix scheme" is useful when you wish to use one Python installation to -perform the build/install (i.e., to run the setup script), but install modules -into the third-party module directory of a different Python installation (or -something that looks like a different Python installation). If this sounds a -trifle unusual, it is---that's why the "home scheme" comes first. However, -there are at least two known cases where the prefix scheme will be useful. - -First, consider that many Linux distributions put Python in :file:`/usr`, rather -than the more traditional :file:`/usr/local`. This is entirely appropriate, -since in those cases Python is part of "the system" rather than a local add-on. -However, if you are installing Python modules from source, you probably want -them to go in :file:`/usr/local/lib/python2.{X}` rather than -:file:`/usr/lib/python2.{X}`. This can be done with :: - - /usr/bin/python setup.py install --prefix=/usr/local - -Another possibility is a network filesystem where the name used to write to a -remote directory is different from the name used to read it: for example, the -Python interpreter accessed as :file:`/usr/local/bin/python` might search for -modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to -be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. This could -be done with :: - - /usr/local/bin/python setup.py install --prefix=/mnt/@server/export - -In either case, the :option:`--prefix` option defines the installation base, and -the :option:`--exec-prefix` option defines the platform-specific installation -base, which is used for platform-specific files. (Currently, this just means -non-pure module distributions, but could be expanded to C libraries, binary -executables, etc.) If :option:`--exec-prefix` is not supplied, it defaults to -:option:`--prefix`. Files are installed as follows: - -+------------------------------+-----------------------------------------------------+-----------------------------+ -| Type of file | Installation Directory | Override option | -+==============================+=====================================================+=============================+ -| pure module distribution | :file:`{prefix}/lib/python{X.Y}/site-packages` | :option:`--install-purelib` | -+------------------------------+-----------------------------------------------------+-----------------------------+ -| non-pure module distribution | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :option:`--install-platlib` | -+------------------------------+-----------------------------------------------------+-----------------------------+ -| scripts | :file:`{prefix}/bin` | :option:`--install-scripts` | -+------------------------------+-----------------------------------------------------+-----------------------------+ -| data | :file:`{prefix}/share` | :option:`--install-data` | -+------------------------------+-----------------------------------------------------+-----------------------------+ - -There is no requirement that :option:`--prefix` or :option:`--exec-prefix` -actually point to an alternate Python installation; if the directories listed -above do not already exist, they are created at installation time. - -Incidentally, the real reason the prefix scheme is important is simply that a -standard Unix installation uses the prefix scheme, but with :option:`--prefix` -and :option:`--exec-prefix` supplied by Python itself as ``sys.prefix`` and -``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme, -but every time you run ``python setup.py install`` without any other options, -you're using it. - -Note that installing extensions to an alternate Python installation has no -effect on how those extensions are built: in particular, the Python header files -(:file:`Python.h` and friends) installed with the Python interpreter used to run -the setup script will be used in compiling extensions. It is your -responsibility to ensure that the interpreter used to run extensions installed -in this way is compatible with the interpreter used to build them. The best way -to do this is to ensure that the two interpreters are the same version of Python -(possibly different builds, or possibly copies of the same build). (Of course, -if your :option:`--prefix` and :option:`--exec-prefix` don't even point to an -alternate Python installation, this is immaterial.) - - -.. _inst-alt-install-windows: - -Alternate installation: Windows (the prefix scheme) ---------------------------------------------------- - -Windows has no concept of a user's home directory, and since the standard Python -installation under Windows is simpler than under Unix, the :option:`--prefix` -option has traditionally been used to install additional packages in separate -locations on Windows. :: - - python setup.py install --prefix="\Temp\Python" - -to install modules to the :file:`\\Temp\\Python` directory on the current drive. - -The installation base is defined by the :option:`--prefix` option; the -:option:`--exec-prefix` option is not supported under Windows. Files are -installed as follows: - -+------------------------------+---------------------------+-----------------------------+ -| Type of file | Installation Directory | Override option | -+==============================+===========================+=============================+ -| pure module distribution | :file:`{prefix}` | :option:`--install-purelib` | -+------------------------------+---------------------------+-----------------------------+ -| non-pure module distribution | :file:`{prefix}` | :option:`--install-platlib` | -+------------------------------+---------------------------+-----------------------------+ -| scripts | :file:`{prefix}\\Scripts` | :option:`--install-scripts` | -+------------------------------+---------------------------+-----------------------------+ -| data | :file:`{prefix}\\Data` | :option:`--install-data` | -+------------------------------+---------------------------+-----------------------------+ - - -.. _inst-custom-install: - -Custom Installation -=================== - -Sometimes, the alternate installation schemes described in section -:ref:`inst-alt-install` just don't do what you want. You might want to tweak just -one or two directories while keeping everything under the same base directory, -or you might want to completely redefine the installation scheme. In either -case, you're creating a *custom installation scheme*. - -You probably noticed the column of "override options" in the tables describing -the alternate installation schemes above. Those options are how you define a -custom installation scheme. These override options can be relative, absolute, -or explicitly defined in terms of one of the installation base directories. -(There are two installation base directories, and they are normally the same--- -they only differ when you use the Unix "prefix scheme" and supply different -:option:`--prefix` and :option:`--exec-prefix` options.) - -For example, say you're installing a module distribution to your home directory -under Unix---but you want scripts to go in :file:`~/scripts` rather than -:file:`~/bin`. As you might expect, you can override this directory with the -:option:`--install-scripts` option; in this case, it makes most sense to supply -a relative path, which will be interpreted relative to the installation base -directory (your home directory, in this case):: - - python setup.py install --home=~ --install-scripts=scripts - -Another Unix example: suppose your Python installation was built and installed -with a prefix of :file:`/usr/local/python`, so under a standard installation -scripts will wind up in :file:`/usr/local/python/bin`. If you want them in -:file:`/usr/local/bin` instead, you would supply this absolute directory for the -:option:`--install-scripts` option:: - - python setup.py install --install-scripts=/usr/local/bin - -(This performs an installation using the "prefix scheme," where the prefix is -whatever your Python interpreter was installed with--- :file:`/usr/local/python` -in this case.) - -If you maintain Python on Windows, you might want third-party modules to live in -a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}` -itself. This is almost as easy as customizing the script installation directory ----you just have to remember that there are two types of modules to worry about, -pure modules and non-pure modules (i.e., modules from a non-pure distribution). -For example:: - - python setup.py install --install-purelib=Site --install-platlib=Site - -The specified installation directories are relative to :file:`{prefix}`. Of -course, you also have to ensure that these directories are in Python's module -search path, such as by putting a :file:`.pth` file in :file:`{prefix}`. See -section :ref:`inst-search-path` to find out how to modify Python's search path. - -If you want to define an entire installation scheme, you just have to supply all -of the installation directory options. The recommended way to do this is to -supply relative paths; for example, if you want to maintain all Python -module-related files under :file:`python` in your home directory, and you want a -separate directory for each platform that you use your home directory from, you -might define the following installation scheme:: - - python setup.py install --home=~ \ - --install-purelib=python/lib \ - --install-platlib=python/lib.$PLAT \ - --install-scripts=python/scripts - --install-data=python/data - -or, equivalently, :: - - python setup.py install --home=~/python \ - --install-purelib=lib \ - --install-platlib='lib.$PLAT' \ - --install-scripts=scripts - --install-data=data - -``$PLAT`` is not (necessarily) an environment variable---it will be expanded by -the Distutils as it parses your command line options, just as it does when -parsing your configuration file(s). - -Obviously, specifying the entire installation scheme every time you install a -new module distribution would be very tedious. Thus, you can put these options -into your Distutils config file (see section :ref:`inst-config-files`):: - - [install] - install-base=$HOME - install-purelib=python/lib - install-platlib=python/lib.$PLAT - install-scripts=python/scripts - install-data=python/data - -or, equivalently, :: - - [install] - install-base=$HOME/python - install-purelib=lib - install-platlib=lib.$PLAT - install-scripts=scripts - install-data=data - -Note that these two are *not* equivalent if you supply a different installation -base directory when you run the setup script. For example, :: - - python setup.py install --install-base=/tmp - -would install pure modules to :file:`{/tmp/python/lib}` in the first case, and -to :file:`{/tmp/lib}` in the second case. (For the second case, you probably -want to supply an installation base of :file:`/tmp/python`.) - -You probably noticed the use of ``$HOME`` and ``$PLAT`` in the sample -configuration file input. These are Distutils configuration variables, which -bear a strong resemblance to environment variables. In fact, you can use -environment variables in config files on platforms that have such a notion but -the Distutils additionally define a few extra variables that may not be in your -environment, such as ``$PLAT``. (And of course, on systems that don't have -environment variables, such as Mac OS 9, the configuration variables supplied by -the Distutils are the only ones you can use.) See section :ref:`inst-config-files` -for details. - -.. XXX need some Windows examples---when would custom installation schemes be - needed on those platforms? - - -.. XXX I'm not sure where this section should go. - -.. _inst-search-path: - -Modifying Python's Search Path ------------------------------- - -When the Python interpreter executes an :keyword:`import` statement, it searches -for both Python code and extension modules along a search path. A default value -for the path is configured into the Python binary when the interpreter is built. -You can determine the path by importing the :mod:`sys` module and printing the -value of ``sys.path``. :: - - $ python - Python 2.2 (#11, Oct 3 2002, 13:31:27) - [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> import sys - >>> sys.path - ['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', - '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', - '/usr/local/lib/python2.3/site-packages'] - >>> - -The null string in ``sys.path`` represents the current working directory. - -The expected convention for locally installed packages is to put them in the -:file:`{...}/site-packages/` directory, but you may want to install Python -modules into some arbitrary directory. For example, your site may have a -convention of keeping all software related to the web server under :file:`/www`. -Add-on Python modules might then belong in :file:`/www/python`, and in order to -import them, this directory must be added to ``sys.path``. There are several -different ways to add the directory. - -The most convenient way is to add a path configuration file to a directory -that's already on Python's path, usually to the :file:`.../site-packages/` -directory. Path configuration files have an extension of :file:`.pth`, and each -line must contain a single path that will be appended to ``sys.path``. (Because -the new paths are appended to ``sys.path``, modules in the added directories -will not override standard modules. This means you can't use this mechanism for -installing fixed versions of standard modules.) - -Paths can be absolute or relative, in which case they're relative to the -directory containing the :file:`.pth` file. See the documentation of -the :mod:`site` module for more information. - -A slightly less convenient way is to edit the :file:`site.py` file in Python's -standard library, and modify ``sys.path``. :file:`site.py` is automatically -imported when the Python interpreter is executed, unless the :option:`-S` switch -is supplied to suppress this behaviour. So you could simply edit -:file:`site.py` and add two lines to it:: - - import sys - sys.path.append('/www/python/') - -However, if you reinstall the same major version of Python (perhaps when -upgrading from 2.2 to 2.2.2, for example) :file:`site.py` will be overwritten by -the stock version. You'd have to remember that it was modified and save a copy -before doing the installation. - -There are two environment variables that can modify ``sys.path``. -:envvar:`PYTHONHOME` sets an alternate value for the prefix of the Python -installation. For example, if :envvar:`PYTHONHOME` is set to ``/www/python``, -the search path will be set to ``['', '/www/python/lib/pythonX.Y/', -'/www/python/lib/pythonX.Y/plat-linux2', ...]``. - -The :envvar:`PYTHONPATH` variable can be set to a list of paths that will be -added to the beginning of ``sys.path``. For example, if :envvar:`PYTHONPATH` is -set to ``/www/python:/opt/py``, the search path will begin with -``['/www/python', '/opt/py']``. (Note that directories must exist in order to -be added to ``sys.path``; the :mod:`site` module removes paths that don't -exist.) - -Finally, ``sys.path`` is just a regular Python list, so any Python application -can modify it by adding or removing entries. - - -.. _inst-config-files: - -Distutils Configuration Files -============================= - -As mentioned above, you can use Distutils configuration files to record personal -or site preferences for any Distutils options. That is, any option to any -command can be stored in one of two or three (depending on your platform) -configuration files, which will be consulted before the command-line is parsed. -This means that configuration files will override default values, and the -command-line will in turn override configuration files. Furthermore, if -multiple configuration files apply, values from "earlier" files are overridden -by "later" files. - - -.. _inst-config-filenames: - -Location and names of config files ----------------------------------- - -The names and locations of the configuration files vary slightly across -platforms. On Unix and Mac OS X, the three configuration files (in the order -they are processed) are: - -+--------------+----------------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+==========================================================+=======+ -| system | :file:`{prefix}/lib/python{ver}/distutils/distutils.cfg` | \(1) | -+--------------+----------------------------------------------------------+-------+ -| personal | :file:`$HOME/.pydistutils.cfg` | \(2) | -+--------------+----------------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+----------------------------------------------------------+-------+ - -And on Windows, the configuration files are: - -+--------------+-------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+=================================================+=======+ -| system | :file:`{prefix}\\Lib\\distutils\\distutils.cfg` | \(4) | -+--------------+-------------------------------------------------+-------+ -| personal | :file:`%HOME%\\pydistutils.cfg` | \(5) | -+--------------+-------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+-------------------------------------------------+-------+ - -On all platforms, the "personal" file can be temporarily disabled by -passing the `--no-user-cfg` option. - -Notes: - -(1) - Strictly speaking, the system-wide configuration file lives in the directory - where the Distutils are installed; under Python 1.6 and later on Unix, this is - as shown. For Python 1.5.2, the Distutils will normally be installed to - :file:`{prefix}/lib/python1.5/site-packages/distutils`, so the system - configuration file should be put there under Python 1.5.2. - -(2) - On Unix, if the :envvar:`HOME` environment variable is not defined, the user's - home directory will be determined with the :func:`getpwuid` function from the - standard :mod:`pwd` module. This is done by the :func:`os.path.expanduser` - function used by Distutils. - -(3) - I.e., in the current directory (usually the location of the setup script). - -(4) - (See also note (1).) Under Python 1.6 and later, Python's default "installation - prefix" is :file:`C:\\Python`, so the system configuration file is normally - :file:`C:\\Python\\Lib\\distutils\\distutils.cfg`. Under Python 1.5.2, the - default prefix was :file:`C:\\Program Files\\Python`, and the Distutils were not - part of the standard library---so the system configuration file would be - :file:`C:\\Program Files\\Python\\distutils\\distutils.cfg` in a standard Python - 1.5.2 installation under Windows. - -(5) - On Windows, if the :envvar:`HOME` environment variable is not defined, - :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will - be tried. This is done by the :func:`os.path.expanduser` function used - by Distutils. - - -.. _inst-config-syntax: - -Syntax of config files ----------------------- - -The Distutils configuration files all have the same syntax. The config files -are grouped into sections. There is one section for each Distutils command, -plus a ``global`` section for global options that affect every command. Each -section consists of one option per line, specified as ``option=value``. - -For example, the following is a complete config file that just forces all -commands to run quietly by default:: - - [global] - verbose=0 - -If this is installed as the system config file, it will affect all processing of -any Python module distribution by any user on the current system. If it is -installed as your personal config file (on systems that support them), it will -affect only module distributions processed by you. And if it is used as the -:file:`setup.cfg` for a particular module distribution, it affects only that -distribution. - -You could override the default "build base" directory and make the -:command:`build\*` commands always forcibly rebuild all files with the -following:: - - [build] - build-base=blib - force=1 - -which corresponds to the command-line arguments :: - - python setup.py build --build-base=blib --force - -except that including the :command:`build` command on the command-line means -that command will be run. Including a particular command in config files has no -such implication; it only means that if the command is run, the options in the -config file will apply. (Or if other commands that derive values from it are -run, they will use the values in the config file.) - -You can find out the complete list of options for any command using the -:option:`--help` option, e.g.:: - - python setup.py build --help - -and you can find out the complete list of global options by using -:option:`--help` without a command:: - - python setup.py --help - -See also the "Reference" section of the "Distributing Python Modules" manual. - - -.. _inst-building-ext: - -Building Extensions: Tips and Tricks -==================================== - -Whenever possible, the Distutils try to use the configuration information made -available by the Python interpreter used to run the :file:`setup.py` script. -For example, the same compiler and linker flags used to compile Python will also -be used for compiling extensions. Usually this will work well, but in -complicated situations this might be inappropriate. This section discusses how -to override the usual Distutils behaviour. - - -.. _inst-tweak-flags: - -Tweaking compiler/linker flags ------------------------------- - -Compiling a Python extension written in C or C++ will sometimes require -specifying custom flags for the compiler and linker in order to use a particular -library or produce a special kind of object code. This is especially true if the -extension hasn't been tested on your platform, or if you're trying to -cross-compile Python. - -In the most general case, the extension author might have foreseen that -compiling the extensions would be complicated, and provided a :file:`Setup` file -for you to edit. This will likely only be done if the module distribution -contains many separate extension modules, or if they often require elaborate -sets of compiler flags in order to work. - -A :file:`Setup` file, if present, is parsed in order to get a list of extensions -to build. Each line in a :file:`Setup` describes a single module. Lines have -the following structure:: - - module ... [sourcefile ...] [cpparg ...] [library ...] - - -Let's examine each of the fields in turn. - -* *module* is the name of the extension module to be built, and should be a - valid Python identifier. You can't just change this in order to rename a module - (edits to the source code would also be needed), so this should be left alone. - -* *sourcefile* is anything that's likely to be a source code file, at least - judging by the filename. Filenames ending in :file:`.c` are assumed to be - written in C, filenames ending in :file:`.C`, :file:`.cc`, and :file:`.c++` are - assumed to be C++, and filenames ending in :file:`.m` or :file:`.mm` are assumed - to be in Objective C. - -* *cpparg* is an argument for the C preprocessor, and is anything starting with - :option:`-I`, :option:`-D`, :option:`-U` or :option:`-C`. - -* *library* is anything ending in :file:`.a` or beginning with :option:`-l` or - :option:`-L`. - -If a particular platform requires a special library on your platform, you can -add it by editing the :file:`Setup` file and running ``python setup.py build``. -For example, if the module defined by the line :: - - foo foomodule.c - -must be linked with the math library :file:`libm.a` on your platform, simply add -:option:`-lm` to the line:: - - foo foomodule.c -lm - -Arbitrary switches intended for the compiler or the linker can be supplied with -the :option:`-Xcompiler` *arg* and :option:`-Xlinker` *arg* options:: - - foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm - -The next option after :option:`-Xcompiler` and :option:`-Xlinker` will be -appended to the proper command line, so in the above example the compiler will -be passed the :option:`-o32` option, and the linker will be passed -:option:`-shared`. If a compiler option requires an argument, you'll have to -supply multiple :option:`-Xcompiler` options; for example, to pass ``-x c++`` -the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``. - -Compiler flags can also be supplied through setting the :envvar:`CFLAGS` -environment variable. If set, the contents of :envvar:`CFLAGS` will be added to -the compiler flags specified in the :file:`Setup` file. - - -.. _inst-non-ms-compilers: - -Using non-Microsoft compilers on Windows ----------------------------------------- - -.. sectionauthor:: Rene Liebscher - - - -Borland/CodeGear C++ -^^^^^^^^^^^^^^^^^^^^ - -This subsection describes the necessary steps to use Distutils with the Borland -C++ compiler version 5.5. First you have to know that Borland's object file -format (OMF) is different from the format used by the Python version you can -download from the Python or ActiveState Web site. (Python is built with -Microsoft Visual C++, which uses COFF as the object file format.) For this -reason you have to convert Python's library :file:`python25.lib` into the -Borland format. You can do this as follows: - -.. Should we mention that users have to create cfg-files for the compiler? -.. see also http://community.borland.com/article/0,1410,21205,00.html - -:: - - coff2omf python25.lib python25_bcpp.lib - -The :file:`coff2omf` program comes with the Borland compiler. The file -:file:`python25.lib` is in the :file:`Libs` directory of your Python -installation. If your extension uses other libraries (zlib, ...) you have to -convert them too. - -The converted files have to reside in the same directories as the normal -libraries. - -How does Distutils manage to use these libraries with their changed names? If -the extension needs a library (eg. :file:`foo`) Distutils checks first if it -finds a library with suffix :file:`_bcpp` (eg. :file:`foo_bcpp.lib`) and then -uses this library. In the case it doesn't find such a special library it uses -the default name (:file:`foo.lib`.) [#]_ - -To let Distutils compile your extension with Borland C++ you now have to type:: - - python setup.py build --compiler=bcpp - -If you want to use the Borland C++ compiler as the default, you could specify -this in your personal or system-wide configuration file for Distutils (see -section :ref:`inst-config-files`.) + install + pysetup + pysetup-config + pysetup-servers .. seealso:: - `C++Builder Compiler `_ - Information about the free C++ compiler from Borland, including links to the - download pages. + :ref:`packaging-index` + The manual for developers of Python projects who want to package and + distribute them. This describes how to use :mod:`packaging` to make + projects easily found and added to an existing Python installation. - `Creating Python Extensions Using Borland's Free Compiler `_ - Document describing how to use Borland's free command-line C++ compiler to build - Python. - - -GNU C / Cygwin / MinGW -^^^^^^^^^^^^^^^^^^^^^^ - -This section describes the necessary steps to use Distutils with the GNU C/C++ -compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter -that was built with Cygwin, everything should work without any of these -following steps. - -Not all extensions can be built with MinGW or Cygwin, but many can. Extensions -most likely to not work are those that use C++ or depend on Microsoft Visual C -extensions. - -To let Distutils compile your extension with Cygwin you have to type:: - - python setup.py build --compiler=cygwin - -and for Cygwin in no-cygwin mode [#]_ or for MinGW type:: - - python setup.py build --compiler=mingw32 - -If you want to use any of these options/compilers as default, you should -consider writing it in your personal or system-wide configuration file for -Distutils (see section :ref:`inst-config-files`.) - -Older Versions of Python and MinGW -"""""""""""""""""""""""""""""""""" -The following instructions only apply if you're using a version of Python -inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with -binutils-2.13.90-20030111-1). - -These compilers require some special libraries. This task is more complex than -for Borland's C++, because there is no program to convert the library. First -you have to create a list of symbols which the Python DLL exports. (You can find -a good program for this task at -http://www.emmestech.com/software/pexports-0.43/download_pexports.html). - -.. I don't understand what the next line means. --amk -.. (inclusive the references on data structures.) - -:: - - pexports python25.dll >python25.def - -The location of an installed :file:`python25.dll` will depend on the -installation options and the version and language of Windows. In a "just for -me" installation, it will appear in the root of the installation directory. In -a shared installation, it will be located in the system directory. - -Then you can create from these information an import library for gcc. :: - - /cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a - -The resulting library has to be placed in the same directory as -:file:`python25.lib`. (Should be the :file:`libs` directory under your Python -installation directory.) - -If your extension uses other libraries (zlib,...) you might have to convert -them too. The converted files have to reside in the same directories as the -normal libraries do. - - -.. seealso:: - - `Building Python modules on MS Windows platform with MinGW `_ - Information about building the required libraries for the MinGW environment. - - -.. rubric:: Footnotes - -.. [#] This also means you could replace all existing COFF-libraries with OMF-libraries - of the same name. - -.. [#] Check http://sources.redhat.com/cygwin/ and http://www.mingw.org/ for more - information - -.. [#] Then you have no POSIX emulation available, but you also don't need - :file:`cygwin1.dll`. + :mod:`packaging` + A library reference for developers of packaging tools wanting to use + standalone building blocks like :mod:`~packaging.version` or + :mod:`~packaging.metadata`, or extend Packaging itself. diff --git a/Doc/install/install.rst b/Doc/install/install.rst new file mode 100644 --- /dev/null +++ b/Doc/install/install.rst @@ -0,0 +1,1029 @@ +.. highlightlang:: none + +==================================== +Installing Python projects: overwiew +==================================== + +.. _packaging_packaging-intro: + +Introduction +============ + +Although Python's extensive standard library covers many programming needs, +there often comes a time when you need to add new functionality to your Python +installation in the form of third-party modules. This might be necessary to +support your own programming, or to support an application that you want to use +and that happens to be written in Python. + +In the past, there was little support for adding third-party modules to an +existing Python installation. With the introduction of the Python Distribution +Utilities (Distutils for short) in Python 2.0, this changed. However, not all +problems were solved; end-users had to rely on ``easy_install`` or +``pip`` to download third-party modules from PyPI, uninstall distributions or do +other maintenance operations. Packaging is a more complete replacement for +Distutils, in the standard library, with a backport named Distutils2 available +for older Python versions. + +This document is aimed primarily at people who need to install third-party +Python modules: end-users and system administrators who just need to get some +Python application running, and existing Python programmers who want to add +new goodies to their toolbox. You don't need to know Python to read this +document; there will be some brief forays into using Python's interactive mode +to explore your installation, but that's it. If you're looking for information +on how to distribute your own Python modules so that others may use them, see +the :ref:`packaging-index` manual. + + +.. _packaging-trivial-install: + +Best case: trivial installation +------------------------------- + +In the best case, someone will have prepared a special version of the module +distribution you want to install that is targeted specifically at your platform +and can be installed just like any other software on your platform. For example, +the module's developer might make an executable installer available for Windows +users, an RPM package for users of RPM-based Linux systems (Red Hat, SuSE, +Mandrake, and many others), a Debian package for users of Debian and derivative +systems, and so forth. + +In that case, you would use the standard system tools to download and install +the specific installer for your platform and its dependencies. + +Of course, things will not always be that easy. You might be interested in a +module whose distribution doesn't have an easy-to-use installer for your +platform. In that case, you'll have to start with the source distribution +released by the module's author/maintainer. Installing from a source +distribution is not too hard, as long as the modules are packaged in the +standard way. The bulk of this document addresses the building and installing +of modules from standard source distributions. + + +.. _packaging-distutils: + +The Python standard: Distutils +------------------------------ + +If you download a source distribution of a module, it will be obvious whether +it was packaged and distributed using Distutils. First, the distribution's name +and version number will be featured prominently in the name of the downloaded +archive, e.g. :file:`foo-1.0.tar.gz` or :file:`widget-0.9.7.zip`. Next, the +archive will unpack into a similarly-named directory: :file:`foo-1.0` or +:file:`widget-0.9.7`. Additionally, the distribution may contain a +:file:`setup.cfg` file and a file named :file:`README.txt` ---or possibly just +:file:`README`--- explaining that building and installing the module +distribution is a simple matter of issuing the following command at your shell's +prompt:: + + python setup.py install + +Third-party projects have extended Distutils to work around its limitations or +add functionality. After some years of near-inactivity in Distutils, a new +maintainer has started to standardize good ideas in PEPs and implement them in a +new, improved version of Distutils, called Distutils2 or Packaging. + + +.. _packaging-new-standard: + +The new standard: Packaging +--------------------------- + +The rules described in the first paragraph above apply to Packaging-based +projects too: a source distribution will have a name like +:file:`widget-0.9.7.zip`. One of the main differences with Distutils is that +distributions no longer have a :file:`setup.py` script; it used to cause a +number of issues. Now there is a unique script installed with Python itself:: + + pysetup install widget-0.9.7.zip + +Running this command is enough to build and install projects (Python modules or +packages, scripts or whole applications), without even having to unpack the +archive. It is also compatible with Distutils-based distributions. + +Unless you have to perform non-standard installations or customize the build +process, you can stop reading this manual ---the above command is everything you +need to get out of it. + +With :program:`pysetup`, you won't even have to manually download a distribution +before installing it; see :ref:`packaging-pysetup`. + + +.. _packaging-standard-install: + +Standard build and install +========================== + +As described in section :ref:`packaging-new-standard`, building and installing +a module distribution using Packaging usually comes down to one simple +command:: + + pysetup run install_dist + +How you actually run this command depends on the platform and the command line +interface it provides: + +* **Unix**: Use a shell prompt. +* **Windows**: Open a command prompt ("DOS console") or use :command:`Powershell`. +* **OS X**: Open a :command:`Terminal`. + + +.. _packaging-platform-variations: + +Platform variations +------------------- + +The setup command is meant to be run from the root directory of the source +distribution, i.e. the top-level subdirectory that the module source +distribution unpacks into. For example, if you've just downloaded a module +source distribution :file:`foo-1.0.tar.gz` onto a Unix system, the normal +steps to follow are these:: + + gunzip -c foo-1.0.tar.gz | tar xf - # unpacks into directory foo-1.0 + cd foo-1.0 + pysetup run install_dist + +On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the +archive file to :file:`C:\\Temp`, then it would unpack into +:file:`C:\\Temp\\foo-1.0`. To actually unpack the archive, you can use either +an archive manipulator with a graphical user interface (such as WinZip or 7-Zip) +or a command-line tool (such as :program:`unzip`, :program:`pkunzip` or, again, +:program:`7z`). Then, open a command prompt window ("DOS box" or +Powershell), and run:: + + cd c:\Temp\foo-1.0 + pysetup run install_dist + + +.. _packaging-splitting-up: + +Splitting the job up +-------------------- + +Running ``pysetup run install_dist`` builds and installs all modules in one go. If you +prefer to work incrementally ---especially useful if you want to customize the +build process, or if things are going wrong--- you can use the setup script to +do one thing at a time. This is a valuable tool when different users will perform +separately the build and install steps. For example, you might want to build a +module distribution and hand it off to a system administrator for installation +(or do it yourself, but with super-user or admin privileges). + +For example, to build everything in one step and then install everything +in a second step, you aptly invoke two distinct Packaging commands:: + + pysetup run build + pysetup run install_dist + +If you do this, you will notice that invoking the :command:`install_dist` command +first runs the :command:`build` command, which ---in this case--- quickly +notices it can spare itself the work, since everything in the :file:`build` +directory is up-to-date. + +You may often ignore this ability to divide the process in steps if all you do +is installing modules downloaded from the Internet, but it's very handy for +more advanced tasks. If you find yourself in the need for distributing your own +Python modules and extensions, though, you'll most likely run many individual +Packaging commands. + + +.. _packaging-how-build-works: + +How building works +------------------ + +As implied above, the :command:`build` command is responsible for collecting +and placing the files to be installed into a *build directory*. By default, +this is :file:`build`, under the distribution root. If you're excessively +concerned with speed, or want to keep the source tree pristine, you can specify +a different build directory with the :option:`--build-base` option. For example:: + + pysetup run build --build-base /tmp/pybuild/foo-1.0 + +(Or you could do this permanently with a directive in your system or personal +Packaging configuration file; see section :ref:`packaging-config-files`.) +In the usual case, however, all this is unnecessary. + +The build tree's default layout looks like so:: + + --- build/ --- lib/ + or + --- build/ --- lib./ + temp./ + +where ```` expands to a brief description of the current OS/hardware +platform and Python version. The first form, with just a :file:`lib` directory, +is used for pure module distributions (module distributions that +include only pure Python modules). If a module distribution contains any +extensions (modules written in C/C++), then the second form, with two ```` +directories, is used. In that case, the :file:`temp.{plat}` directory holds +temporary files generated during the compile/link process which are not intended +to be installed. In either case, the :file:`lib` (or :file:`lib.{plat}`) directory +contains all Python modules (pure Python and extensions) to be installed. + +In the future, more directories will be added to handle Python scripts, +documentation, binary executables, and whatever else is required to install +Python modules and applications. + + +.. _packaging-how-install-works: + +How installation works +---------------------- + +After the :command:`build` command is run (whether explicitly or by the +:command:`install_dist` command on your behalf), the work of the :command:`install_dist` +command is relatively simple: all it has to do is copy the contents of +:file:`build/lib` (or :file:`build/lib.{plat}`) to the installation directory +of your choice. + +If you don't choose an installation directory ---i.e., if you just run +``pysetup run install_dist``\ --- then the :command:`install_dist` command +installs to the standard location for third-party Python modules. This location +varies by platform and depending on how you built/installed Python itself. On +Unix (and Mac OS X, which is also Unix-based), it also depends on whether the +module distribution being installed is pure Python or contains extensions +("non-pure"): + ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Platform | Standard installation location | Default value | Notes | ++=================+=====================================================+==================================================+=======+ +| Unix (pure) | :file:`{prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Unix (non-pure) | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ +| Windows | :file:`{prefix}\\Lib\\site-packages` | :file:`C:\\Python{XY}\\Lib\\site-packages` | \(2) | ++-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ + +Notes: + +(1) + Most Linux distributions include Python as a standard part of the system, so + :file:`{prefix}` and :file:`{exec-prefix}` are usually both :file:`/usr` on + Linux. If you build Python yourself on Linux (or any Unix-like system), the + default :file:`{prefix}` and :file:`{exec-prefix}` are :file:`/usr/local`. + +(2) + The default installation directory on Windows was :file:`C:\\Program + Files\\Python` under Python 1.6a1, 1.5.2, and earlier. + +:file:`{prefix}` and :file:`{exec-prefix}` stand for the directories that Python +is installed to, and where it finds its libraries at run-time. They are always +the same under Windows, and very often the same under Unix and Mac OS X. You +can find out what your Python installation uses for :file:`{prefix}` and +:file:`{exec-prefix}` by running Python in interactive mode and typing a few +simple commands. + +.. TODO link to Doc/using instead of duplicating + +To start the interactive Python interpreter, you need to follow a slightly +different recipe for each platform. Under Unix, just type :command:`python` at +the shell prompt. Under Windows (assuming the Python executable is on your +:envvar:`PATH`, which is the usual case), you can choose :menuselection:`Start --> Run`, +type ``python`` and press ``enter``. Alternatively, you can simply execute +:command:`python` at a command prompt ("DOS console" or Powershell). + +Once the interpreter is started, you type Python code at the prompt. For +example, on my Linux system, I type the three Python statements shown below, +and get the output as shown, to find out my :file:`{prefix}` and :file:`{exec-prefix}`:: + + Python 3.3 (r32:88445, Apr 2 2011, 10:43:54) + Type "help", "copyright", "credits" or "license" for more information. + >>> import sys + >>> sys.prefix + '/usr' + >>> sys.exec_prefix + '/usr' + +If you don't want to install modules to the standard location, or if you don't +have permission to write there, then you need to read about alternate +installations in section :ref:`packaging-alt-install`. If you want to customize your +installation directories more heavily, see section :ref:`packaging-custom-install`. + + +.. _packaging-alt-install: + +Alternate installation +====================== + +Often, it is necessary or desirable to install modules to a location other than +the standard location for third-party Python modules. For example, on a Unix +system you might not have permission to write to the standard third-party module +directory. Or you might wish to try out a module before making it a standard +part of your local Python installation. This is especially true when upgrading +a distribution already present: you want to make sure your existing base of +scripts still works with the new version before actually upgrading. + +The Packaging :command:`install_dist` command is designed to make installing module +distributions to an alternate location simple and painless. The basic idea is +that you supply a base directory for the installation, and the +:command:`install_dist` command picks a set of directories (called an *installation +scheme*) under this base directory in which to install files. The details +differ across platforms, so read whichever of the following sections applies to +you. + + +.. _packaging-alt-install-prefix: + +Alternate installation: the home scheme +--------------------------------------- + +The idea behind the "home scheme" is that you build and maintain a personal +stash of Python modules. This scheme's name is derived from the concept of a +"home" directory on Unix, since it's not unusual for a Unix user to make their +home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. +In spite of its name's origin, this scheme can be used by anyone, regardless +of the operating system. + +Installing a new module distribution in this way is as simple as :: + + pysetup run install_dist --home + +where you can supply any directory you like for the :option:`--home` option. On +Unix, lazy typists can just type a tilde (``~``); the :command:`install_dist` command +will expand this to your home directory:: + + pysetup run install_dist --home ~ + +The :option:`--home` option defines the base directory for the installation. +Under it, files are installed to the following directories: + ++------------------------------+---------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+===========================+=============================+ +| pure module distribution | :file:`{home}/lib/python` | :option:`--install-purelib` | ++------------------------------+---------------------------+-----------------------------+ +| non-pure module distribution | :file:`{home}/lib/python` | :option:`--install-platlib` | ++------------------------------+---------------------------+-----------------------------+ +| scripts | :file:`{home}/bin` | :option:`--install-scripts` | ++------------------------------+---------------------------+-----------------------------+ +| data | :file:`{home}/share` | :option:`--install-data` | ++------------------------------+---------------------------+-----------------------------+ + + +.. _packaging-alt-install-home: + +Alternate installation: Unix (the prefix scheme) +------------------------------------------------ + +The "prefix scheme" is useful when you wish to use one Python installation to +run the build command, but install modules into the third-party module directory +of a different Python installation (or something that looks like a different +Python installation). If this sounds a trifle unusual, it is ---that's why the +"home scheme" comes first. However, there are at least two known cases where the +prefix scheme will be useful. + +First, consider that many Linux distributions put Python in :file:`/usr`, rather +than the more traditional :file:`/usr/local`. This is entirely appropriate, +since in those cases Python is part of "the system" rather than a local add-on. +However, if you are installing Python modules from source, you probably want +them to go in :file:`/usr/local/lib/python2.{X}` rather than +:file:`/usr/lib/python2.{X}`. This can be done with :: + + pysetup run install_dist --prefix /usr/local + +Another possibility is a network filesystem where the name used to write to a +remote directory is different from the name used to read it: for example, the +Python interpreter accessed as :file:`/usr/local/bin/python` might search for +modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to +be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. This could +be done with :: + + pysetup run install_dist --prefix=/mnt/@server/export + +In either case, the :option:`--prefix` option defines the installation base, and +the :option:`--exec-prefix` option defines the platform-specific installation +base, which is used for platform-specific files. (Currently, this just means +non-pure module distributions, but could be expanded to C libraries, binary +executables, etc.) If :option:`--exec-prefix` is not supplied, it defaults to +:option:`--prefix`. Files are installed as follows: + ++------------------------------+-----------------------------------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+=====================================================+=============================+ +| pure module distribution | :file:`{prefix}/lib/python{X.Y}/site-packages` | :option:`--install-purelib` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| non-pure module distribution | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :option:`--install-platlib` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| scripts | :file:`{prefix}/bin` | :option:`--install-scripts` | ++------------------------------+-----------------------------------------------------+-----------------------------+ +| data | :file:`{prefix}/share` | :option:`--install-data` | ++------------------------------+-----------------------------------------------------+-----------------------------+ + +There is no requirement that :option:`--prefix` or :option:`--exec-prefix` +actually point to an alternate Python installation; if the directories listed +above do not already exist, they are created at installation time. + +Incidentally, the real reason the prefix scheme is important is simply that a +standard Unix installation uses the prefix scheme, but with :option:`--prefix` +and :option:`--exec-prefix` supplied by Python itself as ``sys.prefix`` and +``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme, +but every time you run ``pysetup run install_dist`` without any other +options, you're using it. + +Note that installing extensions to an alternate Python installation doesn't have +anything to do with how those extensions are built: in particular, extensions +will be compiled using the Python header files (:file:`Python.h` and friends) +installed with the Python interpreter used to run the build command. It is +therefore your responsibility to ensure compatibility between the interpreter +intended to run extensions installed in this way and the interpreter used to +build these same extensions. To avoid problems, it is best to make sure that +the two interpreters are the same version of Python (possibly different builds, +or possibly copies of the same build). (Of course, if your :option:`--prefix` +and :option:`--exec-prefix` don't even point to an alternate Python installation, +this is immaterial.) + + +.. _packaging-alt-install-windows: + +Alternate installation: Windows (the prefix scheme) +--------------------------------------------------- + +Windows has a different and vaguer notion of home directories than Unix, and +since its standard Python installation is simpler, the :option:`--prefix` option +has traditionally been used to install additional packages to arbitrary +locations. :: + + pysetup run install_dist --prefix "\Temp\Python" + +to install modules to the :file:`\\Temp\\Python` directory on the current drive. + +The installation base is defined by the :option:`--prefix` option; the +:option:`--exec-prefix` option is unsupported under Windows. Files are +installed as follows: + ++------------------------------+---------------------------+-----------------------------+ +| Type of file | Installation Directory | Override option | ++==============================+===========================+=============================+ +| pure module distribution | :file:`{prefix}` | :option:`--install-purelib` | ++------------------------------+---------------------------+-----------------------------+ +| non-pure module distribution | :file:`{prefix}` | :option:`--install-platlib` | ++------------------------------+---------------------------+-----------------------------+ +| scripts | :file:`{prefix}\\Scripts` | :option:`--install-scripts` | ++------------------------------+---------------------------+-----------------------------+ +| data | :file:`{prefix}\\Data` | :option:`--install-data` | ++------------------------------+---------------------------+-----------------------------+ + + +.. _packaging-custom-install: + +Custom installation +=================== + +Sometimes, the alternate installation schemes described in section +:ref:`packaging-alt-install` just don't do what you want. You might want to tweak +just one or two directories while keeping everything under the same base +directory, or you might want to completely redefine the installation scheme. +In either case, you're creating a *custom installation scheme*. + +You probably noticed the column of "override options" in the tables describing +the alternate installation schemes above. Those options are how you define a +custom installation scheme. These override options can be relative, absolute, +or explicitly defined in terms of one of the installation base directories. +(There are two installation base directories, and they are normally the same +---they only differ when you use the Unix "prefix scheme" and supply different +:option:`--prefix` and :option:`--exec-prefix` options.) + +For example, say you're installing a module distribution to your home directory +under Unix, but you want scripts to go in :file:`~/scripts` rather than +:file:`~/bin`. As you might expect, you can override this directory with the +:option:`--install-scripts` option and, in this case, it makes most sense to supply +a relative path, which will be interpreted relative to the installation base +directory (in our example, your home directory):: + + pysetup run install_dist --home ~ --install-scripts scripts + +Another Unix example: suppose your Python installation was built and installed +with a prefix of :file:`/usr/local/python`. Thus, in a standard installation, +scripts will wind up in :file:`/usr/local/python/bin`. If you want them in +:file:`/usr/local/bin` instead, you would supply this absolute directory for +the :option:`--install-scripts` option:: + + pysetup run install_dist --install-scripts /usr/local/bin + +This command performs an installation using the "prefix scheme", where the +prefix is whatever your Python interpreter was installed with ---in this case, +:file:`/usr/local/python`. + +If you maintain Python on Windows, you might want third-party modules to live in +a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}` +itself. This is almost as easy as customizing the script installation directory +---you just have to remember that there are two types of modules to worry about, +pure modules and non-pure modules (i.e., modules from a non-pure distribution). +For example:: + + pysetup run install_dist --install-purelib Site --install-platlib Site + +.. XXX Nothing is installed right under prefix in windows, is it?? + +The specified installation directories are relative to :file:`{prefix}`. Of +course, you also have to ensure that these directories are in Python's module +search path, such as by putting a :file:`.pth` file in :file:`{prefix}`. See +section :ref:`packaging-search-path` to find out how to modify Python's search path. + +If you want to define an entire installation scheme, you just have to supply all +of the installation directory options. Using relative paths is recommended here. +For example, if you want to maintain all Python module-related files under +:file:`python` in your home directory, and you want a separate directory for +each platform that you use your home directory from, you might define the +following installation scheme:: + + pysetup run install_dist --home ~ \ + --install-purelib python/lib \ + --install-platlib python/'lib.$PLAT' \ + --install-scripts python/scripts \ + --install-data python/data + +or, equivalently, :: + + pysetup run install_dist --home ~/python \ + --install-purelib lib \ + --install-platlib 'lib.$PLAT' \ + --install-scripts scripts \ + --install-data data + +``$PLAT`` doesn't need to be defined as an environment variable ---it will also +be expanded by Packaging as it parses your command line options, just as it +does when parsing your configuration file(s). (More on that later.) + +Obviously, specifying the entire installation scheme every time you install a +new module distribution would be very tedious. To spare you all that work, you +can store it in a Packaging configuration file instead (see section +:ref:`packaging-config-files`), like so:: + + [install_dist] + install-base = $HOME + install-purelib = python/lib + install-platlib = python/lib.$PLAT + install-scripts = python/scripts + install-data = python/data + +or, equivalently, :: + + [install_dist] + install-base = $HOME/python + install-purelib = lib + install-platlib = lib.$PLAT + install-scripts = scripts + install-data = data + +Note that these two are *not* equivalent if you override their installation +base directory when running the setup script. For example, :: + + pysetup run install_dist --install-base /tmp + +would install pure modules to :file:`/tmp/python/lib` in the first case, and +to :file:`/tmp/lib` in the second case. (For the second case, you'd probably +want to supply an installation base of :file:`/tmp/python`.) + +You may have noticed the use of ``$HOME`` and ``$PLAT`` in the sample +configuration file. These are Packaging configuration variables, which +bear a strong resemblance to environment variables. In fact, you can use +environment variables in configuration files on platforms that have such a notion, but +Packaging additionally defines a few extra variables that may not be in your +environment, such as ``$PLAT``. Of course, on systems that don't have +environment variables, such as Mac OS 9, the configuration variables supplied by +the Packaging are the only ones you can use. See section :ref:`packaging-config-files` +for details. + +.. XXX which vars win out eventually in case of clash env or Packaging? + +.. XXX need some Windows examples---when would custom installation schemes be + needed on those platforms? + + +.. XXX Move this section to Doc/using + +.. _packaging-search-path: + +Modifying Python's search path +------------------------------ + +When the Python interpreter executes an :keyword:`import` statement, it searches +for both Python code and extension modules along a search path. A default value +for this path is configured into the Python binary when the interpreter is built. +You can obtain the search path by importing the :mod:`sys` module and printing +the value of ``sys.path``. :: + + $ python + Python 2.2 (#11, Oct 3 2002, 13:31:27) + [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + >>> import sys + >>> sys.path + ['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', + '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', + '/usr/local/lib/python2.3/site-packages'] + >>> + +The null string in ``sys.path`` represents the current working directory. + +The expected convention for locally installed packages is to put them in the +:file:`{...}/site-packages/` directory, but you may want to choose a different +location for some reason. For example, if your site kept by convention all web +server-related software under :file:`/www`. Add-on Python modules might then +belong in :file:`/www/python`, and in order to import them, this directory would +have to be added to ``sys.path``. There are several ways to solve this problem. + +The most convenient way is to add a path configuration file to a directory +that's already on Python's path, usually to the :file:`.../site-packages/` +directory. Path configuration files have an extension of :file:`.pth`, and each +line must contain a single path that will be appended to ``sys.path``. (Because +the new paths are appended to ``sys.path``, modules in the added directories +will not override standard modules. This means you can't use this mechanism for +installing fixed versions of standard modules.) + +Paths can be absolute or relative, in which case they're relative to the +directory containing the :file:`.pth` file. See the documentation of +the :mod:`site` module for more information. + +A slightly less convenient way is to edit the :file:`site.py` file in Python's +standard library, and modify ``sys.path``. :file:`site.py` is automatically +imported when the Python interpreter is executed, unless the :option:`-S` switch +is supplied to suppress this behaviour. So you could simply edit +:file:`site.py` and add two lines to it:: + + import sys + sys.path.append('/www/python/') + +However, if you reinstall the same major version of Python (perhaps when +upgrading from 3.3 to 3.3.1, for example) :file:`site.py` will be overwritten by +the stock version. You'd have to remember that it was modified and save a copy +before doing the installation. + +Alternatively, there are two environment variables that can modify ``sys.path``. +:envvar:`PYTHONHOME` sets an alternate value for the prefix of the Python +installation. For example, if :envvar:`PYTHONHOME` is set to ``/www/python``, +the search path will be set to ``['', '/www/python/lib/pythonX.Y/', +'/www/python/lib/pythonX.Y/plat-linux2', ...]``. + +The :envvar:`PYTHONPATH` variable can be set to a list of paths that will be +added to the beginning of ``sys.path``. For example, if :envvar:`PYTHONPATH` is +set to ``/www/python:/opt/py``, the search path will begin with +``['/www/python', '/opt/py']``. (Note that directories must exist in order to +be added to ``sys.path``; the :mod:`site` module removes non-existent paths.) + +Finally, ``sys.path`` is just a regular Python list, so any Python application +can modify it by adding or removing entries. + + +.. _packaging-config-files: + +Configuration files for Packaging +================================= + +As mentioned above, you can use configuration files to store personal or site +preferences for any option supported by any Packaging command. Depending on your +platform, you can use one of two or three possible configuration files. These +files will be read before parsing the command-line, so they take precedence over +default values. In turn, the command-line will override configuration files. +Lastly, if there are multiple configuration files, values from files read +earlier will be overridden by values from files read later. + +.. XXX "one of two or three possible..." seems wrong info. Below always 3 files + are indicated in the tables. + + +.. _packaging-config-filenames: + +Location and names of configuration files +----------------------------------------- + +The name and location of the configuration files vary slightly across +platforms. On Unix and Mac OS X, these are the three configuration files listed +in the order they are processed: + ++--------------+----------------------------------------------------------+-------+ +| Type of file | Location and filename | Notes | ++==============+==========================================================+=======+ +| system | :file:`{prefix}/lib/python{ver}/packaging/packaging.cfg` | \(1) | ++--------------+----------------------------------------------------------+-------+ +| personal | :file:`$HOME/.pydistutils.cfg` | \(2) | ++--------------+----------------------------------------------------------+-------+ +| local | :file:`setup.cfg` | \(3) | ++--------------+----------------------------------------------------------+-------+ + +Similarly, the configuration files on Windows ---also listed in the order they +are processed--- are these: + ++--------------+-------------------------------------------------+-------+ +| Type of file | Location and filename | Notes | ++==============+=================================================+=======+ +| system | :file:`{prefix}\\Lib\\packaging\\packaging.cfg` | \(4) | ++--------------+-------------------------------------------------+-------+ +| personal | :file:`%HOME%\\pydistutils.cfg` | \(5) | ++--------------+-------------------------------------------------+-------+ +| local | :file:`setup.cfg` | \(3) | ++--------------+-------------------------------------------------+-------+ + +On all platforms, the *personal* file can be temporarily disabled by +means of the `--no-user-cfg` option. + +Notes: + +(1) + Strictly speaking, the system-wide configuration file lives in the directory + where Packaging is installed. + +(2) + On Unix, if the :envvar:`HOME` environment variable is not defined, the + user's home directory will be determined with the :func:`getpwuid` function + from the standard :mod:`pwd` module. Packaging uses the + :func:`os.path.expanduser` function to do this. + +(3) + I.e., in the current directory (usually the location of the setup script). + +(4) + (See also note (1).) Python's default installation prefix is + :file:`C:\\Python`, so the system configuration file is normally + :file:`C:\\Python\\Lib\\packaging\\packaging.cfg`. + +(5) + On Windows, if the :envvar:`HOME` environment variable is not defined, + :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will + be tried. Packaging uses the :func:`os.path.expanduser` function to do this. + + +.. _packaging-config-syntax: + +Syntax of configuration files +----------------------------- + +All Packaging configuration files share the same syntax. Options defined in +them are grouped into sections, and each Packaging command gets its own section. +Additionally, there's a ``global`` section for options that affect every command. +Sections consist of one or more lines containing a single option specified as +``option = value``. + +For example, here's a complete configuration file that forces all commands to +run quietly by default:: + + [global] + verbose = 0 + +If this was the system configuration file, it would affect all processing +of any Python module distribution by any user on the current system. If it was +installed as your personal configuration file (on systems that support them), +it would affect only module distributions processed by you. Lastly, if it was +used as the :file:`setup.cfg` for a particular module distribution, it would +affect that distribution only. + +.. XXX "(on systems that support them)" seems wrong info + +If you wanted to, you could override the default "build base" directory and +make the :command:`build\*` commands always forcibly rebuild all files with +the following:: + + [build] + build-base = blib + force = 1 + +which corresponds to the command-line arguments:: + + pysetup run build --build-base blib --force + +except that including the :command:`build` command on the command-line means +that command will be run. Including a particular command in configuration files +has no such implication; it only means that if the command is run, the options +for it in the configuration file will apply. (This is also true if you run +other commands that derive values from it.) + +You can find out the complete list of options for any command using the +:option:`--help` option, e.g.:: + + pysetup run build --help + +and you can find out the complete list of global options by using +:option:`--help` without a command:: + + pysetup run --help + +See also the "Reference" section of the "Distributing Python Modules" manual. + +.. XXX no links to the relevant section exist. + + +.. _packaging-building-ext: + +Building extensions: tips and tricks +==================================== + +Whenever possible, Packaging tries to use the configuration information made +available by the Python interpreter used to run `pysetup`. +For example, the same compiler and linker flags used to compile Python will also +be used for compiling extensions. Usually this will work well, but in +complicated situations this might be inappropriate. This section discusses how +to override the usual Packaging behaviour. + + +.. _packaging-tweak-flags: + +Tweaking compiler/linker flags +------------------------------ + +Compiling a Python extension written in C or C++ will sometimes require +specifying custom flags for the compiler and linker in order to use a particular +library or produce a special kind of object code. This is especially true if the +extension hasn't been tested on your platform, or if you're trying to +cross-compile Python. + +.. TODO update to new setup.cfg + +In the most general case, the extension author might have foreseen that +compiling the extensions would be complicated, and provided a :file:`Setup` file +for you to edit. This will likely only be done if the module distribution +contains many separate extension modules, or if they often require elaborate +sets of compiler flags in order to work. + +A :file:`Setup` file, if present, is parsed in order to get a list of extensions +to build. Each line in a :file:`Setup` describes a single module. Lines have +the following structure:: + + module ... [sourcefile ...] [cpparg ...] [library ...] + + +Let's examine each of the fields in turn. + +* *module* is the name of the extension module to be built, and should be a + valid Python identifier. You can't just change this in order to rename a module + (edits to the source code would also be needed), so this should be left alone. + +* *sourcefile* is anything that's likely to be a source code file, at least + judging by the filename. Filenames ending in :file:`.c` are assumed to be + written in C, filenames ending in :file:`.C`, :file:`.cc`, and :file:`.c++` are + assumed to be C++, and filenames ending in :file:`.m` or :file:`.mm` are assumed + to be in Objective C. + +* *cpparg* is an argument for the C preprocessor, and is anything starting with + :option:`-I`, :option:`-D`, :option:`-U` or :option:`-C`. + +* *library* is anything ending in :file:`.a` or beginning with :option:`-l` or + :option:`-L`. + +If a particular platform requires a special library on your platform, you can +add it by editing the :file:`Setup` file and running ``pysetup run build``. +For example, if the module defined by the line :: + + foo foomodule.c + +must be linked with the math library :file:`libm.a` on your platform, simply add +:option:`-lm` to the line:: + + foo foomodule.c -lm + +Arbitrary switches intended for the compiler or the linker can be supplied with +the :option:`-Xcompiler` *arg* and :option:`-Xlinker` *arg* options:: + + foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm + +The next option after :option:`-Xcompiler` and :option:`-Xlinker` will be +appended to the proper command line, so in the above example the compiler will +be passed the :option:`-o32` option, and the linker will be passed +:option:`-shared`. If a compiler option requires an argument, you'll have to +supply multiple :option:`-Xcompiler` options; for example, to pass ``-x c++`` +the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``. + +Compiler flags can also be supplied through setting the :envvar:`CFLAGS` +environment variable. If set, the contents of :envvar:`CFLAGS` will be added to +the compiler flags specified in the :file:`Setup` file. + + +.. _packaging-non-ms-compilers: + +Using non-Microsoft compilers on Windows +---------------------------------------- + +.. sectionauthor:: Rene Liebscher + + + +Borland/CodeGear C++ +^^^^^^^^^^^^^^^^^^^^ + +This subsection describes the necessary steps to use Packaging with the Borland +C++ compiler version 5.5. First you have to know that Borland's object file +format (OMF) is different from the format used by the Python version you can +download from the Python or ActiveState Web site. (Python is built with +Microsoft Visual C++, which uses COFF as the object file format.) For this +reason, you have to convert Python's library :file:`python25.lib` into the +Borland format. You can do this as follows: + +.. Should we mention that users have to create cfg-files for the compiler? +.. see also http://community.borland.com/article/0,1410,21205,00.html + +:: + + coff2omf python25.lib python25_bcpp.lib + +The :file:`coff2omf` program comes with the Borland compiler. The file +:file:`python25.lib` is in the :file:`Libs` directory of your Python +installation. If your extension uses other libraries (zlib, ...) you have to +convert them too. + +The converted files have to reside in the same directories as the normal +libraries. + +How does Packaging manage to use these libraries with their changed names? If +the extension needs a library (eg. :file:`foo`) Packaging checks first if it +finds a library with suffix :file:`_bcpp` (eg. :file:`foo_bcpp.lib`) and then +uses this library. In the case it doesn't find such a special library it uses +the default name (:file:`foo.lib`.) [#]_ + +To let Packaging compile your extension with Borland, C++ you now have to +type:: + + pysetup run build --compiler bcpp + +If you want to use the Borland C++ compiler as the default, you could specify +this in your personal or system-wide configuration file for Packaging (see +section :ref:`packaging-config-files`.) + + +.. seealso:: + + `C++Builder Compiler `_ + Information about the free C++ compiler from Borland, including links to the + download pages. + + `Creating Python Extensions Using Borland's Free Compiler `_ + Document describing how to use Borland's free command-line C++ compiler to build + Python. + + +GNU C / Cygwin / MinGW +^^^^^^^^^^^^^^^^^^^^^^ + +This section describes the necessary steps to use Packaging with the GNU C/C++ +compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter +that was built with Cygwin, everything should work without any of these +following steps. + +Not all extensions can be built with MinGW or Cygwin, but many can. Extensions +most likely to not work are those that use C++ or depend on Microsoft Visual C +extensions. + +To let Packaging compile your extension with Cygwin, you have to type:: + + pysetup run build --compiler=cygwin + +and for Cygwin in no-cygwin mode [#]_ or for MinGW, type:: + + pysetup run build --compiler=mingw32 + +If you want to use any of these options/compilers as default, you should +consider writing it in your personal or system-wide configuration file for +Packaging (see section :ref:`packaging-config-files`.) + +Older Versions of Python and MinGW +"""""""""""""""""""""""""""""""""" +The following instructions only apply if you're using a version of Python +inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with +:file:`binutils-2.13.90-20030111-1`). + +These compilers require some special libraries. This task is more complex than +for Borland's C++, because there is no program to convert the library. First +you have to create a list of symbols which the Python DLL exports. (You can find +a good program for this task at +http://www.emmestech.com/software/pexports-0.43/download_pexports.html). + +.. I don't understand what the next line means. --amk + (inclusive the references on data structures.) + +:: + + pexports python25.dll > python25.def + +The location of an installed :file:`python25.dll` will depend on the +installation options and the version and language of Windows. In a "just for +me" installation, it will appear in the root of the installation directory. In +a shared installation, it will be located in the system directory. + +Then you can create from these information an import library for gcc. :: + + /cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a + +The resulting library has to be placed in the same directory as +:file:`python25.lib`. (Should be the :file:`libs` directory under your Python +installation directory.) + +If your extension uses other libraries (zlib,...) you might have to convert +them too. The converted files have to reside in the same directories as the +normal libraries do. + + +.. seealso:: + + `Building Python modules on MS Windows platform with MinGW `_ + Information about building the required libraries for the MinGW + environment. + + +.. rubric:: Footnotes + +.. [#] This also means you could replace all existing COFF-libraries with + OMF-libraries of the same name. + +.. [#] Check http://sources.redhat.com/cygwin/ and http://www.mingw.org/ for + more information. + +.. [#] Then you have no POSIX emulation available, but you also don't need + :file:`cygwin1.dll`. diff --git a/Doc/install/pysetup-config.rst b/Doc/install/pysetup-config.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup-config.rst @@ -0,0 +1,44 @@ +.. _packaging-pysetup-config: + +===================== +Pysetup Configuration +===================== + +Pysetup supports two configuration files: :file:`.pypirc` and :file:`packaging.cfg`. + +.. FIXME integrate with configfile instead of duplicating + +Configuring indexes +------------------- + +You can configure additional indexes in :file:`.pypirc` to be used for index-related +operations. By default, all configured index-servers and package-servers will be used +in an additive fashion. To limit operations to specific indexes, use the :option:`--index` +and :option:`--package-server options`:: + + $ pysetup install --index pypi --package-server django some.project + +Adding indexes to :file:`.pypirc`:: + + [packaging] + index-servers = + pypi + other + + package-servers = + django + + [pypi] + repository: + username: + password: + + [other] + repository: + username: + password: + + [django] + repository: + username: + password: diff --git a/Doc/install/pysetup-servers.rst b/Doc/install/pysetup-servers.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup-servers.rst @@ -0,0 +1,61 @@ +.. _packaging-pysetup-servers: + +=============== +Package Servers +=============== + +Pysetup supports installing Python packages from *Package Servers* in addition +to PyPI indexes and mirrors. + +Package Servers are simple directory listings of Python distributions. Directories +can be served via HTTP or a local file system. This is useful when you want to +dump source distributions in a directory and not worry about the full index structure. + +Serving distributions from Apache +--------------------------------- +:: + + $ mkdir -p /var/www/html/python/distributions + $ cp *.tar.gz /var/www/html/python/distributions/ + + + ServerAdmin webmaster at domain.com + DocumentRoot "/var/www/html/python" + ServerName python.example.org + ErrorLog logs/python.example.org-error.log + CustomLog logs/python.example.org-access.log common + Options Indexes FollowSymLinks MultiViews + DirectoryIndex index.html index.htm + + + Options Indexes FollowSymLinks MultiViews + Order allow,deny + Allow from all + + + +Add the Apache based distribution server to :file:`.pypirc`:: + + [packaging] + package-servers = + apache + + [apache] + repository: http://python.example.org/distributions/ + + +Serving distributions from a file system +---------------------------------------- +:: + + $ mkdir -p /data/python/distributions + $ cp *.tar.gz /data/python/distributions/ + +Add the directory to :file:`.pypirc`:: + + [packaging] + package-servers = + local + + [local] + repository: file:///data/python/distributions/ diff --git a/Doc/install/pysetup.rst b/Doc/install/pysetup.rst new file mode 100644 --- /dev/null +++ b/Doc/install/pysetup.rst @@ -0,0 +1,163 @@ +.. _packaging-pysetup: + +================ +Pysetup Tutorial +================ + +Getting started +--------------- + +Pysetup is a simple script that supports the following features: + +- install, remove, list, and verify Python packages; +- search for available packages on PyPI or any *Simple Index*; +- verify installed packages (md5sum, installed files, version). + + +Finding out what's installed +---------------------------- + +Pysetup makes it easy to find out what Python packages are installed:: + + $ pysetup search virtualenv + virtualenv 1.6 at /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info + + $ pysetup search --all + pyverify 0.8.1 at /opt/python3.3/lib/python3.3/site-packages/pyverify-0.8.1.dist-info + virtualenv 1.6 at /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info + wsgiref 0.1.2 at /opt/python3.3/lib/python3.3/wsgiref.egg-info + ... + + +Installing a distribution +------------------------- + +Pysetup can install a Python project from the following sources: + +- PyPI and Simple Indexes; +- source directories containing a valid :file:`setup.py` or :file:`setup.cfg`; +- distribution source archives (:file:`project-1.0.tar.gz`, :file:`project-1.0.zip`); +- HTTP (http://host/packages/project-1.0.tar.gz). + + +Installing from PyPI and Simple Indexes:: + + $ pysetup install project + $ pysetup install project==1.0 + +Installing from a distribution source archive:: + + $ pysetup install project-1.0.tar.gz + +Installing from a source directory containing a valid :file:`setup.py` or +:file:`setup.cfg`:: + + $ cd path/to/source/directory + $ pysetup install + + $ pysetup install path/to/source/directory + +Installing from HTTP:: + + $ pysetup install http://host/packages/project-1.0.tar.gz + + +Retrieving metadata +------------------- + +You can gather metadata from two sources, a project's source directory or an +installed distribution. The `pysetup metadata` command can retrieve one or +more metadata fields using the `-f` option and a metadata field as the +argument. :: + + $ pysetup metadata virtualenv -f version -f name + Version: + 1.6 + Name: + virtualenv + + $ pysetup metadata virtualenv --all + Metadata-Version: + 1.0 + Name: + virtualenv + Version: + 1.6 + Platform: + UNKNOWN + Summary: + Virtual Python Environment builder + ... + +.. seealso:: + + There are three metadata versions, 1.0, 1.1, and 1.2. The following PEPs + describe specifics of the field names, and their semantics and usage. 1.0 + :PEP:`241`, 1.1 :PEP:`314`, and 1.2 :PEP:`345` + + +Removing a distribution +----------------------- + +You can remove one or more installed distributions using the `pysetup remove` +command:: + + $ pysetup remove virtualenv + removing 'virtualenv': + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/dependency_links.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/entry_points.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/not-zip-safe + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/PKG-INFO + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/SOURCES.txt + /opt/python3.3/lib/python3.3/site-packages/virtualenv-1.6-py3.3.egg-info/top_level.txt + Proceed (y/n)? y + success: removed 6 files and 1 dirs + +The optional '-y' argument auto confirms, skipping the conformation prompt:: + + $ pysetup remove virtualenv -y + + +Getting help +------------ + +All pysetup actions take the `-h` and `--help` options which prints the commands +help string to stdout. :: + + $ pysetup remove -h + Usage: pysetup remove dist [-y] + or: pysetup remove --help + + Uninstall a Python package. + + positional arguments: + dist installed distribution name + + optional arguments: + -y auto confirm package removal + +Getting a list of all pysetup actions and global options:: + + $ pysetup --help + Usage: pysetup [options] action [action_options] + + Actions: + run: Run one or several commands + metadata: Display the metadata of a project + install: Install a project + remove: Remove a project + search: Search for a project + graph: Display a graph + create: Create a Project + + To get more help on an action, use: + + pysetup action --help + + Global options: + --verbose (-v) run verbosely (default) + --quiet (-q) run quietly (turns verbosity off) + --dry-run (-n) don't actually do anything + --help (-h) show detailed help message + --no-user-cfg ignore pydistutils.cfg in your home directory + --version Display the version diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -1,3 +1,5 @@ +.. _abstract-base-classes: + :mod:`abc` --- Abstract Base Classes ==================================== @@ -12,7 +14,7 @@ -------------- This module provides the infrastructure for defining an :term:`abstract base -class` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this +class` (ABC) in Python, as outlined in :pep:`3119`; see the PEP for why this was added to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.) diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -37,14 +37,18 @@ *fileobj*), or operate directly on a named file (named by *filename*). Exactly one of these two parameters should be provided. - The *mode* argument can be either ``'r'`` for reading (default), or ``'w'`` - for writing. + The *mode* argument can be either ``'r'`` for reading (default), ``'w'`` for + overwriting, or ``'a'`` for appending. If *fileobj* is provided, a mode of + ``'w'`` does not truncate the file, and is instead equivalent to ``'a'``. The *buffering* argument is ignored. Its use is deprecated. - If *mode* is ``'w'``, *compresslevel* can be a number between ``1`` and - ``9`` specifying the level of compression: ``1`` produces the least - compression, and ``9`` (default) produces the most compression. + If *mode* is ``'w'`` or ``'a'``, *compresslevel* can be a number between + ``1`` and ``9`` specifying the level of compression: ``1`` produces the + least compression, and ``9`` (default) produces the most compression. + + If *mode* is ``'r'``, the input file may be the concatenation of multiple + compressed streams. :class:`BZ2File` provides all of the members specified by the :class:`io.BufferedIOBase`, except for :meth:`detach` and :meth:`truncate`. @@ -70,6 +74,10 @@ .. versionchanged:: 3.3 The *fileobj* argument to the constructor was added. + .. versionchanged:: 3.3 + The ``'a'`` (append) mode was added, along with support for reading + multi-stream files. + Incremental (de)compression --------------------------- @@ -106,14 +114,20 @@ incrementally. For one-shot compression, use the :func:`decompress` function instead. + .. note:: + This class does not transparently handle inputs containing multiple + compressed streams, unlike :func:`decompress` and :class:`BZ2File`. If + you need to decompress a multi-stream input with :class:`BZ2Decompressor`, + you must use a new decompressor for each stream. + .. method:: decompress(data) Provide data to the decompressor object. Returns a chunk of decompressed data if possible, or an empty byte string otherwise. - Attempting to decompress data after the end of stream is reached raises - an :exc:`EOFError`. If any data is found after the end of the stream, it - is ignored and saved in the :attr:`unused_data` attribute. + Attempting to decompress data after the end of the current stream is + reached raises an :exc:`EOFError`. If any data is found after the end of + the stream, it is ignored and saved in the :attr:`unused_data` attribute. .. attribute:: eof @@ -127,6 +141,9 @@ Data found after the end of the compressed stream. + If this attribute is accessed before the end of the stream has been + reached, its value will be ``b''``. + One-shot (de)compression ------------------------ @@ -145,5 +162,11 @@ Decompress *data*. + If *data* is the concatenation of multiple compressed streams, decompress + all of the streams. + For incremental decompression, use a :class:`BZ2Decompressor` instead. + .. versionchanged:: 3.3 + Support for multi-stream inputs was added. + diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -458,7 +458,8 @@ .. method:: reset() - Reset the encoder to the initial state. + Reset the encoder to the initial state. The output is discarded: call + ``.encode('', final=True)`` to reset the encoder and to get the output. .. method:: IncrementalEncoder.getstate() diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -23,7 +23,7 @@ .. versionchanged:: 3.3 Formerly, this module was part of the :mod:`collections` module. -.. _abstract-base-classes: +.. _collections-abstract-base-classes: Collections Abstract Base Classes --------------------------------- diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -34,7 +34,7 @@ ===================== ==================================================================== .. versionchanged:: 3.3 - Moved :ref:`abstract-base-classes` to the :mod:`collections.abc` module. + Moved :ref:`collections-abstract-base-classes` to the :mod:`collections.abc` module. For backwards compatibility, they continue to be visible in this module as well. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -29,6 +29,8 @@ Hashing Methods --------------- +.. versionadded:: 3.3 + The :mod:`crypt` module defines the list of hashing methods (not all methods are available on all platforms): @@ -37,33 +39,26 @@ A Modular Crypt Format method with 16 character salt and 86 character hash. This is the strongest method. - .. versionadded:: 3.3 - .. data:: METHOD_SHA256 Another Modular Crypt Format method with 16 character salt and 43 character hash. - .. versionadded:: 3.3 - .. data:: METHOD_MD5 Another Modular Crypt Format method with 8 character salt and 22 character hash. - .. versionadded:: 3.3 - .. data:: METHOD_CRYPT The traditional method with a 2 character salt and 13 characters of hash. This is the weakest method. - .. versionadded:: 3.3 - Module Attributes ----------------- +.. versionadded:: 3.3 .. attribute:: methods @@ -71,8 +66,6 @@ ``crypt.METHOD_*`` objects. This list is sorted from strongest to weakest, and is guaranteed to have at least ``crypt.METHOD_CRYPT``. - .. versionadded:: 3.3 - Module Functions ---------------- @@ -108,9 +101,8 @@ different sizes in the *salt*, it is recommended to use the full crypted password as salt when checking for a password. -.. versionchanged:: 3.3 - Before version 3.3, *salt* must be specified as a string and cannot - accept ``crypt.METHOD_*`` values (which don't exist anyway). + .. versionchanged:: 3.3 + Accept ``crypt.METHOD_*`` values in addition to strings for *salt*. .. function:: mksalt(method=None) @@ -124,25 +116,27 @@ 16 random characters from the set ``[./a-zA-Z0-9]``, suitable for passing as the *salt* argument to :func:`crypt`. -.. versionadded:: 3.3 + .. versionadded:: 3.3 Examples -------- A simple example illustrating typical use:: - import crypt, getpass, pwd + import pwd + import crypt + import getpass def login(): - username = input('Python login:') + username = input('Python login: ') cryptedpasswd = pwd.getpwnam(username)[1] if cryptedpasswd: if cryptedpasswd == 'x' or cryptedpasswd == '*': - raise "Sorry, currently no support for shadow passwords" + raise ValueError('no support for shadow passwords') cleartext = getpass.getpass() return crypt.crypt(cleartext, cryptedpasswd) == cryptedpasswd else: - return 1 + return True To generate a hash of a password using the strongest available method and check it against the original:: @@ -151,4 +145,4 @@ hashed = crypt.crypt(plaintext) if hashed != crypt.crypt(plaintext, hashed): - raise "Hashed version doesn't validate against original" + raise ValueError("hashed version doesn't validate against original") diff --git a/Doc/library/depgraph-output.png b/Doc/library/depgraph-output.png new file mode 100644 index 0000000000000000000000000000000000000000..960bb1b5639e7ff615ddbd6cbf8a542be31d5fe7 GIT binary patch literal 24719 zc%00D3x*H at FQBqn;>Fx%f zvCg^v&-J;VcyqtH&%wiiz4ux(#u&fvZ_c?4Qk0j(!=c1Mp-_0zQsT-e6j~DeVaLLR z-&~f}{RZDK4WCMiqy8fQrZ(n8p-?wa(&CR*T@%+P-LzHrFCJ};;GW)HV<`K|kcx%F za>LfzBD>aDIw9D7-Soc4&y0!mXp=+d^#wI&_EX(*9+!0PYHg+VZ3xv$fRUa7-6(|1^pbKZhJFaw zu$TRS0sP35=y=^Igd#L=6zy)OK(c6>$df0R+1S~Yo%*F=3f`WpptLx{sHVk=r`Bs)E zhb1K?K1oSQeMOCpjd$NDv5<(q`IMjkRyj}n$&)7;k{TKmGBPrXs;a)}=?o-fWa*ii zm&7j-6BE0-xutpky}-i76_=92VqjpH+1%{SxQXc#g>RHZL^%6B?jFD662ZXWU_?xe z|Jj+RRF?A5 at i9FM3lY?#zrB3T#7e=fmq^_l16i1BVZKMJG$H3qytLj(@RPSP7gOF9UQpvX&(kA+_!6m zenmt?wBieLaNt%|RT&11TUu69#>K_)zdGZGw!AnydXXsTg1 at k^a9!AwU*bJ&Xn%$z z>me|h z5)RPjv+2L*bgzzPufQli{Cl=5B_%b(cv?TVu)x5 at ML6wsNVBuELqJUYmR!%1P~p)z z&-d@&+wtF5Vn92bO5R?%_WRHKM-nnJIGERHLms?b&|mqPm#%xXxmKZhJ2EP&)P3L5 zdb)|m*4EbbbiI1J^(yD*fdS>Utx=4bHug?|ud{6dT-Kv^LuiF4q1{r_(k(&6%v%Fb zIbXC|yjErFh~+Zcf;;@)neUFhYk)rW>eS}w=t#dKm~{Q1meJG`vc<~md9m&jPtS+H zfB)9EvwL4r!9&e&k18!KH4GTO<>v1GJHNO|R9Balh=`~}zXjdb*H?eK$;&XHa{~h= zW;{qOzXMW)kbuCa+^pBIH(6-3-0T`e2ZOWuwaet>eukKivI( zuf}OLW;CsoZ^lX>r1GuRNRdHj2*uI);q>-uYq$s57Kxc`%2Nl+=&Q zs8hc`{fS{fyXI?{uxt8X!f37wI&;u^tZ^kibR&Y{Clk!H?Uv!p3fiQV`EJ8p_q+F>9)h+>=Z#-MImzxg$lX0X8%AeKJfOrC zgl5Yn`2YTGxHjFaw}*|9WDqb-VOTSglkzHfzWd{!-yQFCR*HU2q9K=`sh)n-1|eX7 zu%>Zzdist=KIhl03#Pa)gpE;qAfbAbXDwW}9=R?a10y4s=aGGZda3A|BFcWiq6adN zkc#Tv(~oyrCMLAj>_`7 at eX!`%Ts}MAMM~M)Sb69`ie_P__r)%qZ$N<9osVKnQS^L# zWP&amJnAmcd3zU^fZEyzCx at HwE3HOWhE(!Y)ys^rMa9JEqq=THbrDcf2Ag!pq@|^y zp$O>ct_6v|LBqfl$sfY$9kQ&veperLlL$N6>p;VxR-A#0U&Z=QXJ}w(C{li)e9tT{ z2Dt4mq<#AINk~oMo&PnuFk!C~{lRQGiRJf|L|mPkCeQ{R{m-b3y)5NC^Y5`-mp;#k zNgle0ioR)amzI_m)yYzp?(grHtD+z$mt>0$hMM}dzdr)i2NUDBSgchYhEjxxUS9Z- z;Lf#VUa1)`;A9zfe(CaMrDxBcT`6u66h7M$16|;j(JOF5R6_=un4wW_N|99z^FfR% zD=keM%6~pss8yZY)RY`XD^wI$HRU+-8BLij+VT9v$sIxq8x>0ZKsmSG zb=weK1Ro#2!lau_nS~@%k;Qy>;fJxEodU{yc_2$%yuzRj6J11DSU6KT4 at ytO`}fz- zQsEYS!TVF0`s>R(wG-8 z`O%oT*G1?&w_Yoq;9z6Zqbgqf=`>wkc0Q5}qqeAM$jz0K(iCWEX}RP>L`=LtK2~8t zjF#Hhr)V&CwEYJgRj6GX*>tkPjxM5-BX7fvne_Fm6uO9og at wD5(~INN)BC4&gh~tOuP}|VuUT4J$Nq?7 at msdUe zl)SpE>RbCojVeWiUjbZ?*aF{dmzT6){lmV zhe4 at Go1C?(6E~>m&{0r&Q((^HtApP$>`8Jb6GKVvN0k(;W$TnX9U*Y9I|!TT<_p#=jS* z>XnwH at EZTDqcX^Q{WWK2=cD}*Jta-e;H4#V5_0l)G|JW4{pMT0-*Fm_m6?n}HiKYw z;0N&{GI`kb<;#`kzZZhCa&ib;WM*dv!v|EAmES;Bpl4;pu6Nm7D9+uOgI*n=w6(Rv zw1q%X#WwKfk4ZJu%{WH_ at R!T;uwa#f(-^hs3*}Nbc8UHXS=>Z=;ker?E z_Dadg`878`nsWVvmu$Y}qsm6wbi6aY{;8tS(%LGzwk41S{WsWO8G?4B+b{l{r?P86b8&Hr zU^KcGjId_;RXVoF48Y#;eAc5rnVC0 at jg3Edbzv(AAKy%N{f*t;-d?dnB~ULAD)AQ7 z34yqy?Jsl at adFt!u3eLjOOy5Yq5RB(7xVBq#eZMe)ImurPoF;hI`06wg6-tg{9H{kV*fTRQcnwf<G{ zT3QBVNf0-nf_srM85xZ3`zx0 at IXVC1I)ywANY*#?t4g< z|F*GodrHQk?qksAPr-3I|51;Cl=Lzc6&0A>8*FSi6IC`=Dh)8h>J6 at 3{`fTGpK9R0 z!PkV3QjaBqxQ5r!Qsol(2vIAa>ixn38yhD)FOC=e_%?0p^X7lBvasB^diCmf&5I1( zF|!n}?2+V+Qp1j5wJ%mn$3HZ{zJN+8D=8^OIk_TDmMC-C)Sb-%`;>Ia54%8PL zAOAZqC)u*%;r;vMn+?18D8#|AaB?Cs0pf8975m6r7;35}shz(54FoSE at STahi+xMV{a~B#X><(Uj zn*zQ7<4di_xOsSZu=aO$cj+Ufz&~CqRAc9O^l~AjZvlwUcV4rQ?BL)aT8Rq!E#97 zB+{&N%quzjnWu8er=g+2*F>{0CR;vf+}Qi^++I#m36o&tCuPTmUUKS;(WxQiyloJ^tlVA3eIrJ+mGj^&Uo= z&g&?|v9xZA|6D>trFdUF2%~<0e&xy)>#?%S0K at PFjNuQCM_E~U3o86o8>rSO)T`6= z`vzkmcZA at f!ovv=Kd4 at mPfSI{&T$Ifv&3!J)YZeo2tpbuEizf65)zmaA=h6Q6mXoK zPXBEx9;pL&f%?px;`t^rlE|Eg@C3yt<2Z&{P^-E0M!S)xeQ2?W7m8hw*2`F6M8)_^hmwXT(Ve-64n;tdy`?sjLIPeY=%5iJvv5dSt6RHBTmVv?H#S41W zhlB+7hk8s=aBVIwdSYVYNSUmg(K6Bu5m+zcB at A2kTBLZ&V z!40OHyh^I7I=@CRayiUNeKqD at o2b6_;K2iy+qeC4a+p0mJ$)Ak|H^Y&@KC~Jf>&)^ zZg)}8HGelcs*bE^zsk(uje{%P8B|{vKqOA5@~*QPIeSS}-ERTdIU!pX_eCXDV8?dnLeq=5nbPfK1Hf)~pJw-EMf z3%J%?JVHT36B8Vy^o&; zbU4p{BSnd*tH;jb*a(**xi#ZG;%NFKerT?eAWK;q)I?5x8)7-@Yq>Yd2`zk&WBh4l>qS6#>((s_jub8*&<-$K+2FCtDk^TWv$Nyi<7a~sE#0D~0enOkX#~$(_PwnwqiZxWDvDKDI2n9Y z*Z1!skZCL|EP)F>NfYL#T3XJ(yf2QK8 at F1o&i(l#1`%RxVQn0+gK*zh at 9dxRxs9*qD zeuo*;^V*MY5%81?;OeYPMHnBZU#r at dRFI@)xKJw%%$WDZ8Ph7V6H$8SE3&%Lbj;Lr zabi^}Mp&R-OJvu$Pv(BOF=BcAR4vwRBp at cvxIgZ8vYhh-T6G0^bEoO| zSbFV2E-tReApP!pOY{z^YX+TQ5Ny|gx`-qM#C?Gx0;vf-Mv-MPs`ARpj+z&LP$&?R zSRkjbgrxyVd825KWPnJm8J|AkKvX_^_AGQoRZWdAUf0sV04+|I>CDE^5FLmcXs)%h z6BFT|?)kg- at 82I^)tAjuPRq{5thSr>|93$Pb-qrHVq;^QSzNq=+S=Z3nQHVfu(2tu z{_*W!i!jlUltjb9!Exhbcj#{VsMw#hvqXHtS#UIfRFdH7z$@7AF38O)fklUKOoL`Y z^Fa02`dncS;B&JxGblkp!M&BCt571B`ZEHy>dVXTK`i1y7K0i%nLjMB>a)r3=;#30 zB&RhoF>!Am`S~-osHjKZaM_%Xj}O_90{^hKwl)JchMAd}|G|S6V1c8F{(eHR5555b zSG2XY^)0`BX_!>{C?_D3MMTc2EAH&fcSonr_w3A5yV0HW`1lyvO!M+;R2+eL94$Ru z8za7R=Z?LzvwvY>VK{CY09lHnbKJh&0i{_{ON+h22rhsa95=U?i3zHysi~#u=0`AU zSKyaYS)OVY`6?_VH4gJQ4liH&*&M(t$U5SS7hFX;^~2^9+`POt6~xURk{i%nD=Vu; z!obi_Jh*{@kr9T7_vz)0MBRH_TrJaoFI+fu8?KX)k+n+wwXHLe$x at cG-QVAD4g3Ti z68H at QgoT}*IC6FpduPK&n=QJvqvNuzt*!mbmv8Iq1+{f_X8-)b(9_e~TOPd92)^vI zi%(G2ATtfPab%;=*!af1d&HnspP|-;r=$R4Uj>alIy%A@*VokWxV_Ko z$%NqY^YeqUD)RX8>u`~)I5_Z;_uvdsV4q3R(a{MA2z)@P8F_dR*0y(YB0VN8 at fZTT z2!{3Rw{M~_V=yF$i-pQCv+yGUwXx)qM;2VrF)+C7XG9t?M2DRm>oQ*+ z at 0es}Wz8OK|AEZEB%dVU7avav&UkNgnhwgzKNEJa{w_831`JJ(7VaP^&gHW5@`$9Q z(5vKkZh#xt(9l4pkcScvaSODxVOv}FzJ7iNM_aS4fuT+fptgVDvq-m0O_{jw-FpG| z%pI~+*VJsCp4J{E{*YBb* zFmXi`6$wN|MG2^>f8D~rTQArj)syw~qy5}hLTX{p>v?&3ENpCVWSPYN-FPJ+BlCyW z?5&O{Y>HX0^;`-BdjMREK|w)*bQiMX5>z^n&Gybt2B0OdGMMHg0Of&koKbp*6^P~L=GOXJ z#NEBl-oL%42Om%- at ZCExD9kX#NAbB|Ln0lKp#YzUxDqLOd4J792}egBCfQgYK-wt+ z0d**!VYEWQ7+3I-y}cU8Wg>`zy9TY7WaD|TfgSxJ6Gjc3DS at r{?PpNnpzOhXY1cVo zJJeDmHv|IhOB3UA-O`^$7h3fM+UrSq^d3h4>|nwU*(VPU4xX8t^No$Y{?F3VJyYDX z^Yae;%8BKYOqJ))1CZAJ=?ooh_I?D^+8IXkPCAOoU~RP2^OL0b$2&T$VKjmzK*?tp zr<*0^h- at HLb_ICxH*F<1~krh|ZBl}sb2i)9|lG8fc^73K! zHzFb<-%#DRMV5eI)LZAeqChEIt~5*ZZAdS|Pe&{H#U)OwYCngEe{X-GlN1$2havhb zIhfS9zdC{}2s*6}Bm4eahlgL_+xEayPNBWS8Dvd=xLEH!va6n>kRtJ(R>-%1+UUK| z at Y37nwOLVdWN*I8ZaQpzqM8x(y{M=tmj49sCA1Je_&?(A1;8XB&T~-V zkzDh|2|F`o_99e09`6fJD0z%|sxojZmi4K|gbK~V(KI2F4Z-D`%*=zSkKanMMGq8c zl+)HR8agkg8bZABK-hreDzz45ThvX+ftjDnmUVX7ZCSbR#t$0-`U=# z2b$KbFel{Y;R&QsE0<4xC=FrFgyMmGI)TZS&gc)MAzMxFNqiuNEIz2HsO;?Qq{F=L zeq9u_=#1xs4!MMLZ at e!h5faT_}22}dNfvl%p- at XMiFfuN~{~88lF2aEFxNK-6 z{c&7U6mVP$AEhr1kb3n>__)rg*V z5($o9?smz>TN(5R>=Vu&F6sq7dkmB)|K z`~m`^8XJYqPgaX1Hkx#HmBW`g1wb+*^VLZU>~);{n8MwVEwE-4B3 z^zvfm;rRfe6*_*{Sl1d>&q_n+;Zc2jw%dEvW@^$|r8`tEPjvt+N7t`kiLZ|5$(0P3 z*y23{$Zl%_IXOFmS{Ze=)#XOBKaZ4U$^c@%p4AK at N%_$A?h^?KWfPMur4ws>=A5hmvqk*%d|t=mk)fR%B4!{Gm--h0VBJAA+)F<3xLfPYVcNrZhqR4z>poca4w7Tie)J9ITBwo*vk| zl~k-V!SQ>e>%M%;!O`(1F)?x4S at ra*e})`bC at wx82^pc2r3_4FiKX#R1qGRL_sk*z zJRdxG&>wm0X<*{Q-EpJ3Cm& zb}H|Qc0V-Bk53^*_%_FgIghcKnIsDExL8S>iqAR~GyzzI5l9RvQP2r3J7e=D?@!3S zH4?EnSFbYGYRiL-om*Lvfzpr$I#uEB#WS)vY4W3TNSV$MLYmRr+Z!@GVl>TB#(h%} z#5688R?*V()AenF{-j<_0In4qSz=~+YrbVrwY)LBv#9_`0T3Pv>(z}W$M>0;H{n); zS{Fc~)otVEPyZPO_v87GtbBY`VyCfOMwoK&NwHJ&cQMXBGFeClCKM2plaH`$1055h z1e{hrlvsB~-hz~tVuiW1#^0l{7Ueq421{x8su&z68gI zLPElS>8!6Vyfp{lE1qTM+9aRH}F)=e!0c<%x-}Gii z85G^j>1og&WrLY2*gM09jC6mS+s#<$1{1B&topLKW7IFwUVA9ISQC?Hv8zd5oI zkDRkG>I|`PN+^^QxIMHf8?;~xX296eQby2agGBIyyyWJj`{{Z$>%)iIA?laTPxcv6 z72ba at B)SjRCq~vVYdsEa->%;R0fJP at dtR&yA01!H{W>r(ps&TOkW3OYS at R-eY~G=^ zVRE7-B{sqRyb~!I=zRv{%H?HcSg0gHmm;z8X1yQlXa8N1wHdDn@)2|~9XbBL*JS&X zq=~`7AVL^_-;P#8QxiwBZ+mZ_e6Qlc<-o3kuX3k at x{r_65rLs{0b1&C9_3I!eGE#J7W5azOZj}W?tXB9w<{Mp1CNTwt zv|ZzV%&38*fV*DQNV%E9hv?|Z`kJSA_p-F;y!HqKv5*b=JGu>lb#(#+gsN=M%55Nx zD=geRs$Mj6x%hL^)W7(H3H=D+e*XM93OO4SP%%yMkKyw;lmHWtcx12BgO>4eN=C`B zb{Hr6sIC&bY2mrKxzvgZlH}y%t?g~XWQD&8T-p8Rsqi&qnKooe_2Z_Mxp__TsG*Tj z1Q at -xfNMse>8=ZLX8LAk0dRFgfP-rXtuGd>vgycx)LIX|Z8+GGjaOQcLmPSO`pm8C z2CeGG?h2e9ZrTkh5fDbi#ZjR3)!$dvny~ENxnh&iXh_!PGVLV^ibUfs*9Un(#;NNMvN>-nT02v2+*r&_MH(z2!?jP3H$%D`4S-E{^_)j at 7*Q1Ey4p zAMay$c;8YjSWg>)%g3n`3bwX)&~C)ZGI9K~DA_gdfS!8TvJ2imz%Vm|s&EJI@&0n7 z7L+Y&8XAlB at k$2YmtPX>nphKEgaJ_VRM`aJ+wtjXwOh{W!h!_Ke74n3RZUHzva+%Q zW>TX3kLF+uSCqU*2Z#R`T8|K2*I7UO^*?%lPspJ#Iep^PUmYuFMoR?_*4R8%`~NyG z<9F@;lu(3E;L?O$^DR_s_4cca<3-W2U{ZE06rxqo*VB!9iC&#@Q#>>mrkDb)>aZf+ zMj23oOjWjJklno>_ow?x4BC88Y{p)tr>C0(1*)p6OIcRNf9vk{bKMYrGWzS}27`fU z+r8e0Vn_{9Wn+EtAg-aYkuEs%p54?#s7>Jzf-;!Xh29stDI_E$H^(`02L_Z^hVnm7 zx&6T=W+Ff#s}`!wwRmcZ988`s^Z$?2u0seZyek at K%k8&euvA13fNvRf zK3U&bVRC9w)CfFQVfjBx$s<30t$vec78Fc?{5;0&lDm6k3;DUTwUs)e>+xfB8w-M5 z{Lh#7%yF_3RaI4cADhpfTrU$46ukdw;+KDpTK+QK-=iyTuCCz_fcwjX0c3ZyrS|vt z|I-6i4Grmwi;KPA?>H&5np0k#1bzShUEs$^#&b2bfo{%bWFw$;xxapz`2TN3n#aw4 zad!4GD%WLmN-hRzLt;J^(9 at E`byi;DmnxP19?KL8ok4{NLLgWbgx?}4kF4aiwL zq;3xn431$b@)ykE4X-^ruaEHWPd9BD*syyserf`e0=;pNP{4vw`%$S7&BQ} zS##(m=A)}^>XMp`?z|u#0{|UM00xEugUgjG#!KXSo{yFDK0xYS&cLJcKHvZ62-m)? z+Sj(>o>?e^B-GThU@#pI)-+1n(&pxj9h{w+9zA*lRqEsDY>Dj+X667Ug=AT{2n5CG z+ at AfgdVcX|o9U(`_k%TQ=tcSz?uVeKg=&L{1}`iukkHV`!BiRs+yrBhZI-{aaA at 6^YA_&`F* zZH$F~Gr4<1Uq^P at lSNeBraqgdG3f`^NAy06F- zXh4AAQ}c at qX3H@?efkuXH0}MPi&!=`Hn6JQ9y1EhCL7$M$T-wR0QPRcJL2z|$p?5d zBso!sN{BU|?Y!H{GJ1RES~l1|=W!Jan+T9oK at Ja&lfQx>QzlA3621 zuL&Rd00c?{Zw3-Fn(wa+xgS0 at J}jOT{-&j(B9^aKnC|0)0{2HkO8NwT8aTDo9)6%x zWB(c%jQ^ZejAD{Y7Yo1-qEQO~;L3cKuhtJm77JBdUq6Uc1dqdw`Q at X@zOiyMi~jT{ zBxGa~;KC91e0xp!uB!+A!OTr at m&wfr8UjM(Sp}!nVS|Y(8*_8>&zaIucfC#=A3}LA zDJ!$=-5A9{*2=1ECxh{*_-+UZ(M(NENl8h4{vLO4c6F8A*;NABCOq5e=0x at bfgf&s z?B0ffHX6v3M$RNboU%Fx79_Do%TNoslhiw}w;rrdL?k3!wX?H(xZO at 1`_PRW(40Pc z#cTDd74v$sH?ml}NukBoc+?W2c*wXCEBtJIFH%>8HG at b29bIlZ+n0=nSa z!{{D`?d>^c=HxKmzKsV6iJXdpzRAfBp8YHHet`pS9cv4ws0E4M$f>24)HIcuYcp at aPu1Y!cwtUON4|w zySpGOe&uGpI6(_g&+hW_c6@$~K}bOn6u~ITaOV!bt*xzL!1o)<1GOXT6V)%E4Vl^5 z47|Lg;KAN#7W$W$-$TZimNu-U?iK#~vo%*w}bxZLD08 zEgD&91b`$YCVmSOf=m1GI+#$yfHTE@%gP$pZH9rtLBFI)$O$Dqy=%~=qvK;KnVo%|ntB8G--UMM2qHQLh5>lb9d`Y~A=aocdM76* zWB~4H*W6h1K^}|h{>XWiDzmWgc0)tM%>4Xi$Yxh}_tv2yQsmTGem;9*Qqt_&+Ar23 z1AtnD2mK%lj&OZsRmPErm68#z0s zp+SK_=Cs|fn%7n%MQJrP*TG{;LN3Y3$oQ^nGemrDYZK$-Iz2gQ?d`n=)|jE0`yjPW zcECbLOblaZXUCUjA2|h?lEQhWqpUozltPK3rly{OJ0geY#>ODyF&%2D;S0E~q_Wa4 zCgtNsHPGGt^k^(cfv%>m&bg1$*l+;C_tm)okacimBoXo$-oKl6ot0K2 z$b)&H-suGevYWLrF)^a(Wo2b=U{(qW3k?hm(2x^n8X7GF14REGM+=w9f;1Vl`mBrl#ie zj~{qo7ww&#`~m{5Kt=YOYV^oJretU5ji28Wj{?nMX{Y1NK}uwYSb_u?`JY*zZo2)@ zG3fC}7GOV1D=Q@(olwyJug2WScBZ5;3S@&SG~U|UTHn$V2Xt0lORKG?2OkDDynDW+ zs>&Zah3s92)F6sN-Jz+e8C+_qP7Y=eFO1sp(dxZBm$OGihNSBu82KDLpL zwCw?OuL1$Mu_50K16oJD>g{LIAu*6M$sx2tnrrsz_dCfkG{d8!25p3sdTDj1z5fb< zb=m&P_&$&ZXLW&pxnky9H2c=!A-N!K=SG5NVW&SH)m@`b++ at dA@h at 8XS6wsP>gqsL zkOV0={Xry1(#gNf0~k$BN=o{0z(8jlYA14b5INT?W)Ko3|1$X9J2VtHT(Sp5og2Nt z9b2o#&A&OlkKc`^-Np2Yk}rp_NAr0U-dR at wueN^shNF@#O9)p+o^MivX+ at p)-o88h z%=7R0q3cHN;*qd%!Qf2hU`TK<4n)g#z_|Ly56Q`4FBf~Z^LU5z;8POtsrL@*ANS7> zrx{sTup%NNU_ at f!X7>P<_?JuWDhZC?DE-}GQ$6o<-fY>pR=uw80yOdhw`We%%8Hm688McZmtE(hpSR=t zaS0_lUibKloFbv8r at zi+=nGxU4nQ7jizqAOKHF-$7Axpd1iv&z&T!B&K%V;n+-A!s zu{pDZP_#?uPyiH%HigBP_Q)2h{b~Mt&T0BR7OhtMjx+ziuglBJV>Txwm-d*i4i|py z?rzI3ZbClH8w8z$SnHAwaH3#WEBK5YHU&0^StyXsHoVdox4+bn0itbUVq)*$KqN at r z8Sl6@%0(^cjO%@IoCA#-=Ad2X5&LNFsQ2Qtx>=>;vNA4>013!FDNIIu2i&|);pHwX z-*B8xlP3kx^gj+C?p+xO_jY7Vg1Q~SXi#8*9FT;f_%=u)lEyBr=Gth zm2(+{36z8cf^!dMY6foK0zhv72?E1YiSyo3li>RGKv1XBHuFpfN^ETGrT&a7naZp; ziLg;K;B{gJoY)c*6M?$+Xbm+>^wA)|nJjVrjm^xAwtshA7jQJsa2g{6Y3*!q+a(|) z!>rZDzk2m5sPAm_bKS=V25Bve$gt3PZna=^G+B>vLoNU9N3M(Vk>3`k(lVPYLd|^C zdxc;LQXY(q-sa}ASWi?H4)u~-)vwsM$2&nnqKnMW&&v&?iF9g51I9J( zo)QQnU4B! z9sIx>W20_sRs=%s=Ya`Fc2ZDZfBi}XrPs2S3|aqny{?z+1O=+R4CTVM?APeuwYrN9 zdHzC;JN^)QQL;=KT~W+b9CZBlH*V`T#Ny!Kgiyyd9q1~U^(4}x08dOxJX?LSZ+`4X z9tM(I2TzS`&TuvzrT6b_d~nnpFVf6NP4yw;)RhI0wf^!o5b;eY#3s9&Af5=dcX7Ho z?Q%*}sY7uULf9`&EZ{f96K3~@aKO}0UXsb_p`oFpiRlYWW at hHt`1qCR`$J7dYg6uZ zRs=t8+jaf-9QADCHiVPnvuC${D&-Fy?F}jr($eCCEXT&hwSYuzZ*NP<%iC6+|M$Q& zW_NFrU;uJ}4J=GxSXk$$XZf`8f+B$D|2!s#8}p^JGrg{k60C)_O8r&xJH81CR2K); z%@iEZSx91qJorE?koW_yO$4kQx`OO)gBkJxC4>vi_!Nw*{Lfi{xjA3tN!-5|=kDuy zLzZWYkN!S(b>*LPcwo#;0eDT-QK+0(V%$aK>+dhh6!n-Xik^puq&w!e82poQ;5d;D zV$te%6?rrRpc*+F0>#Z{NWk2p-crWR?SWdMrr*+%xvPiApCp&5mfDw#<3A;yf at wmb z?wNk?V;{UN=y|l|RXwdV5#1k{v|slIF}7!CXSgwGq$7%s-U`UR%Fe>LU0(5m;oYB2 zYWZ2f)O^PcK!Tq>ePUop2UeawtV~}X%ppbz*w6U1?9d20_m%ewKLsl!>S1bX%Jbs4 zxQwi<_4d!M^Mdy=TG{oU>ZBmPXbZk*8e2qa#aTB|QM0*eJZ~ zcTd$lFHj4N$w*^UR`ZHCW_wg>Y at jG}ztVEk at 1Eo)t-P;C&fkCmSO^_)X(Urt^g ztI)xyQN^oscV!k5xvIZ6CZg|@P9~WaQ$MWl zW);=5FVgcv1+%h?Qe0&ZDhBx4|a=Q*+X|2cztc(|HQr${2MUH;#?(Y}6 z=)8=QH!+!~`rB9+8J3ntkMa2uIvO$7rI6mmd%`Kbt`C#T8WmZLL%3q%jO!!AtD^#>(9UQ3>nk-4&4l(q*VnK5;HGg=3A|Qnjf_Noz;u{C+s9{2 z)6egGEN}8U<+iii#GGLH?d>H47DV}0+}cF7!u)h?DWgjVOLeKz>!v1Q48_f$)twy& z%-rNXwLSW%F3Mm2**ukcjmeI1n=z>FTDO*SjojsQPD#mGmU#xNY$jq$OSz(?ZaNL~ z-d}E5c8`fAtoZNAojfi}W+wB$A5 zXDJBc{n6}NX-O{LO8Z$+=iLRl`R35yEDe>B@bF<77MKlOJ{gYHFIf|CpRi z>S%AzwQ;ur-;SFr_}e(7bZ*WVlgAE6>2cD3y7TAD`#6ys`cS!?hFQZXsRULmSKehF zDL1@&JaW9dI27ZEiBJ6%RRTPP`N#76WW5W;){e2Y5y>NakemG?1t}^0rlzKEoTOV0 zzVoxQEr^a#)3BM#42;#j%;DDPNw{C!MTgm`8?%Nk*V{-=LQ>+qK3+OAGb1s<`rFRZ zU5 at K~_vG3E)cF-pOlN0jT+~FlnZnz1w(OA=c2r-6ZT1dKgX zgp|6B49 at C!W&U_%4^-ysTV*x$0s`^#i;MSQ at Bkp|!5F>^4mJb?58>+6*49>+mBnRe zVbOP}O^p8Vp=7i9Z&MGUwHL`V3A5hhLYGDcKHB$R{BbE-85kMI26GgsycC>{Go;P- zSBAbd>(tmAl>aTNeI}u+tNXpPGkZ$uAfJS552OItg)2|>8)!vbWhF1hg`QMj)>Cp! zpUYRSl>h#1sP^nx2N4m`hsCS9=eSL$8-kcV6jW5 at Aa*6lt12pO?S?O41n%9t=M1Q+ zrliyYu4fdY{sTGp$aAT_Q9homyz@`=3Ms-SP{*vlhSRgDgxp>pdM73(D!S6hzt at u_ zDA)A9?vTAmalj2jtJ>B?LPBBj61TQAbLc)!Kfiaw;K*wh{ z_0Ys5L7l at CfJJ|@&dEqXKtT2;QR!=pD`g;>BOb}~&tU4l_w|J%yH?|2?AlDovlUE4 zL6i at xx6Y1Vni?3iWGkdxNK7cJsda)kj|&RICJqw+-rfClzKR{<=(b){qK3Nq-899o z1%-tg_V#!4^YZdsP60-=%1!ZBM~dkNM at Gz`OCTJdWS>gkBm%I_wl>n&{|v(SrM0bX z`h at 89iTTN^j?r!mOfxexxP7eDO~am^p0%ynw*4xbALqeV9~`F?_4RL*S643zgz%Yc z{Hld!D;n8#w_NTJDtq(h4W;!x?+ef2G_fl^*;KqV>(8Bd&6JX z8wl^;zrVDy!obQJw5m8BV%L052J_;l&aogs5<0WA6iCP at F@ya50ZC5R=!B8K=m>ep zTwGG}C4tVwx*z=!-5Qtgr z0CA~z>6yD%9taAGDJWcnTg?lQq(1 at 4ECJ*Q>@dW=e%EK!9?Rmzp84BH=Ii5?{4N{R zkpG=dEaFeK8(awy$ORO>MV(%0p1Dir>FH^|zw&HuZcao`FJ;wUipu%#g%>|R|L3VG zT0j+>;qq`Si+3!`4SrXy(ITsVM?2k|rEs&NHhLRX4GjtiVHAq|jFnun!#0i0IM!R9NVjk->{P z+uMCt!vp$O)v2ps77f29+o!(Q2b#3RWL|Gz_P at wm-f=7 zOZuk=>qlq1y|wrO<~~Rxz&L at q41D+Qt;mfTft#ZIX>CrZ at vptT*Dhba9Q*IXEi=o@ zT~1QIVj3D6$iZN0YHH-X2GV~CMjBq^*k*cq`VwV`%P3SgF56%HHFb5rfg~O4Z|?MD zWM)W&a2=hV{(%|b_d5B%TDa~&s at pGqjqH_5GO}JGD-mzVxOmNLMzRuRMcJz)T&~TP z8!da3n^hDcn~acKq(n#=$qdQ(o#*$ye^%e_z0dhR=QEz?oTKn#VWE~St||}p-=iBN zrK^0v*MbL`;BPtl%!DF%mV;G)e5j<6k&!_&vIZ#>^nBXpW-uzq1~x=Vjm&j50BR zDWSaqyg*q?tNrRqHEL2)EC9osf5!KclX#WP&npO(=N3>5KtutbqEn#YkdTYRW%iH_ zySK_;Z7~6tip$7Yh1knvpeixca)^cwz&lSC{!9CrS(m@${QMZLy=~xr>VdX!L}{rstdqXhj!i8)rJ~}*=I`Ilt*tcC(b4F(E=Mz} zhKwDkBR*3#vK;X9a_FRi%V^{?bvZC7B+8Qz$k{3WIZc?&$X)P=)P(3~% z^VA6}_9LBvG9N1FQ9X0U?ELvSV5_E)k-PJ$udhH(e3_h#JS^+*s9uJHA*Z;Qum_HJ zW~@O)_wD|{=cYnbouTVL;!s29m!=4AMNe*|Ed%tv9s(sJHd@4#$wwt6$IDuUF}uI}!zXul{yZuz1zBJu)(VQI!sX39 ztK`Jg=W#{D3cZjQa+kXg`p*ndf!AukMMYD?rjNeh-x&ju at ImQ!?i?QmvNAgDd*b9t zbB8ywoN*(x*-Cq&B?8GMQm1!r_369Wven=V}6rjE(O--tm)z#%M%{1uL zzP^6D^v_!gB?|nLvi}SQX!OQXGktd<{NkCs6a>Qw$P*kML z-t&FF(XcUQF{b$<8UpozA zhw^4mu^!_}SRQfB&VBik$IQ&E+jX@*c$s==Xs9M=@#y9aHJ82zak%@6k9X8A=;-MD z9WZwgAVP>M!DnYH;N8$r9)z- at x>{#(tO1SpL!%18fj_VdUz==a{`&p9h?3Ib#_bhm zUq3&RAr8k1tT6$U*&IcW=KIZjdQsjzo~<5!v^9p+!k8?fMu9!v1o0Ug8{<~LsS1+9 zHtZ9F`@HyU6%|Mo#7z77`IFo!Md)G_lt$)>i;>;zQw93BZMM0#fKT;IOmxl7In&b8 z(B%#6GKflvl#7dt^ic6jbV1Zjl6>9W9ceA~PiUy}QPp4!Gc$8dT^$--=I!GXQCoZZ zRz^M#KR-VUuObVuvIKv3hbSD%P+DdI-oGl6m+(N?z zwFqnt?-`=xV%FCDe~dQ@`1tq)ug&b=T3=ue3JOBs0m60Q{d=!C+~g?gqImEiv7q3u zg2F;gvD at er4MMjGuMYK^)NhPkwe5OndP5IDJ*g-B2R3pnSi}L;;pX32eAX6qXLPEZ{K1dKN=_&M0`D?fwI@@ z^2XhGcp$%`f&;9F4!oQ!)etlcfn?h$&Jc|~(UJaQYH_qyzJyFhV-`RLDP3vP=DBnC zZro|VZ>Z%E%`ZZu&q4(S01ylEMIGvcBZ^J3OQawNgIB&Xq6+z*4B33Y?|tZe6r{`W zga>P_T{0>)nH?-dl_7cg`JdWO8REU8(~`MBlsBhKSa|>VAcrRqrpm*2B>CgW`YtYF zVkTKEKxwcKKYaM$&Ce;s6PK2Jr=+B$1 zEd($KrTbT#q+Rr3l@ z^75#Ylan`Bv-c7~o`Cezb~b(UgiAtFvNcWAu;S`x{RQ>&D?#AIw2j6l+d}oGAc~SqD zS^htdt7Q$8-y9?AIbOaT4O*i&Q!WbhfW=G0{iu(rl!XD z)9_(%`^kK#^E{7{3`QQA<@0#9uMf`JaFMP;d^S}@JL=AiAT^3 zs7cuDsXf!;Qc`V2xcg1qT6%i1Pwlm}|KFtv(hrqM1#hiM06e4;i4n_FoirHKO;%N< zkeQh&sHn&_Jv}WhE898NaQ*G8uMa`9< zdQe%d)ocn!Qb)j$$hGn(PZFsdkC|k7l6IFGiCACXr`_}L$4eONa)*ZW^1_0G3ZJQt zO87-`KmsIU3?SK4d$4s!FwcSQ=>9B#r=@8EAUWsyIqS at IZj6ho>$zin at Eb|bHx|cT zG1ed<$AUlYiHnGctOH6`*+8g{AOCBB8vdD3SSZ@&B*(|k|9&hxFEyv6gbBE$dzf5O z0^%sAygX%Y&I7TBMUjzv)fbJ*KG+11P_SwOk!aT7#md4WNYpbmGovEv6+AUw{y-0Y z|E#6u<2H%gU2|uXs{`fmAX?B+I8nnpRp>Pxzvn=q=2r=%P3dfHC9s3}1zeMC;%;q; zX7*YAh69-qB}e!8?8g!xZ~KyMpl-xC0KF3mY*+;Y$x51Esb~7}@MS8qCDR#O6{fdv19-I|dx7-NOy at QBrLsv&12G0~OHH4+FqtTZ9PU z%&n~%?i$g77%S5f!utU-pnIUc2d60|VRZZUp&}g+VPJn4n3$+BiM&c|m;rG0n5Gg- zGE$Zhp1;JzoIX~$2aNTMj|*T5S#L#l%>JM%7X%6lc&F9*fL-Dw^t7M{EB1_f$vP za{bpYONnTgAD6qdJ}}C^F0Ew|k~Nf3HmUwzNbtMq^#P zyxv4cMV-gta1H8P=8w}$&p(R+rI0c^KQB+zYXg)xkHtoI2gXE4OMK$y=B at xOSGlz0 zO~S8wJV^42dinWP*nM=unwZE^y`iILtMUGd%_Z2p5X=@}CZ+=i4ghlATDgaAKa)j- zwB-TzgcIfdR#8E0@^|o(;F){(oaN-?kRM%HSxIj{gs-1}l&X=i^siGy6Vlw=#D^#9 zDX3-!%@_VP_dea5A!J_?pgaT;qz7sprKO|utf~0f2bP2zYnX9R{mqj3aTW(mWK^`=A%tR}pb!dpIE@&~vRQxO0Wd)`)mIj8> z4)xrSF{rK#j^y+?q!(LUc?crjkXhRe6KvJ!?*J`=ju^xp_& zUZtyF5 at cWHBzQB1(D*;>Q!x^|{a;fy*osad at BIf4;(_oY`irObV^Benu!ufTa{zA9~kIYioEQ+~JFyc>&_HsV-ezU7G(IhSaRAWZ*9U z#W8*mJm5Sb6=_0$%@q>W-+{A0@%5e^6h)PU^704HmDxoYiD`|$3Paya6wz&IZ`b*) z=Y@?8H60YX_5^@^WMl-{k-$JjKzvYv)F8BAXScwvZn(bj->_LncXviZL&Iu^!hUWo zP>Vl5*AXHksYh%5=utJ{%^hXPLO^_Q{q)G>oj%<>GIE5CjcsPIFyW(EIfaL7$?RE6Ja|y!IEfnL at 9&SqkXqQ5cm|L# zB=fHgAqiv0HrZ$Y(n@{E3JPYcuTb;Kdi}tWe8E)K3tKWdQ$O$+9*7W(bqB7F2g!T F{tpk90)YSk diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst --- a/Doc/library/distutils.rst +++ b/Doc/library/distutils.rst @@ -12,18 +12,26 @@ 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C. -This package is discussed in two separate chapters: +.. deprecated:: 3.3 + :mod:`packaging` replaces Distutils. See :ref:`packaging-index` and + :ref:`packaging-install-index`. +User documentation and API reference are provided in another document: + .. seealso:: :ref:`distutils-index` The manual for developers and packagers of Python modules. This describes how to prepare :mod:`distutils`\ -based packages so that they may be - easily installed into an existing Python installation. + easily installed into an existing Python installation. If also contains + instructions for end-users wanting to install a distutils-based package, + :ref:`install-index`. - :ref:`install-index` - An "administrators" manual which includes information on installing - modules into an existing Python installation. You do not need to be a - Python programmer to read this manual. +.. trick to silence a Sphinx warning + +.. toctree:: + :hidden: + + ../distutils/index diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -290,19 +290,18 @@ The resulting list is sorted alphabetically. For example: >>> import struct - >>> dir() # doctest: +SKIP + >>> dir() # show the names in the module namespace ['__builtins__', '__doc__', '__name__', 'struct'] - >>> dir(struct) # doctest: +NORMALIZE_WHITESPACE + >>> dir(struct) # show the names in the struct module ['Struct', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from'] - >>> class Foo: - ... def __dir__(self): - ... return ["kan", "ga", "roo"] - ... - >>> f = Foo() - >>> dir(f) - ['ga', 'kan', 'roo'] + >>> class Shape(object): + def __dir__(self): + return ['area', 'perimeter', 'location'] + >>> s = Shape() + >>> dir(s) + ['area', 'perimeter', 'location'] .. note:: @@ -333,15 +332,21 @@ :meth:`__next__` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the corresponding value obtained from iterating over *iterable*. - :func:`enumerate` is useful for obtaining an indexed series: ``(0, seq[0])``, - ``(1, seq[1])``, ``(2, seq[2])``, .... For example: - >>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): - ... print(i, season) - 0 Spring - 1 Summer - 2 Fall - 3 Winter + >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): + print(i, season) + 1 Spring + 2 Summer + 3 Fall + 4 Winter + + Equivalent to:: + + def enumerate(sequence, start=0): + n = start + for elem in sequence: + yield n, elem + n += 1 .. function:: eval(expression, globals=None, locals=None) @@ -580,7 +585,7 @@ Two objects with non-overlapping lifetimes may have the same :func:`id` value. - .. impl-detail:: This is the address of the object. + .. impl-detail:: This is the address of the object in memory. .. function:: input([prompt]) @@ -652,10 +657,10 @@ One useful application of the second form of :func:`iter` is to read lines of a file until a certain line is reached. The following example reads a file - until ``"STOP"`` is reached: :: + until the :meth:`readline` method returns an empty string:: - with open("mydata.txt") as fp: - for line in iter(fp.readline, "STOP"): + with open('mydata.txt') as fp: + for line in iter(fp.readline, ''): process_line(line) @@ -1169,8 +1174,9 @@ It can be called either on the class (such as ``C.f()``) or on an instance (such as ``C().f()``). The instance is ignored except for its class. - Static methods in Python are similar to those found in Java or C++. For a more - advanced concept, see :func:`classmethod` in this section. + Static methods in Python are similar to those found in Java or C++. Also see + :func:`classmethod` for a variant that is useful for creating alternate class + constructors. For more information on static methods, consult the documentation on the standard type hierarchy in :ref:`types`. @@ -1270,6 +1276,10 @@ references. The zero argument form automatically searches the stack frame for the class (``__class__``) and the first argument. + For practical suggestions on how to design cooperative classes using + :func:`super`, see `guide to using super() + `_. + .. function:: tuple([iterable]) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1019,6 +1019,19 @@ Availability: Unix, Windows. +.. function:: pipe2(flags=0) + + Create a pipe with *flags* set atomically. + *flags* is optional and can be constructed by ORing together zero or more of + these values: :data:`O_NONBLOCK`, :data:`O_CLOEXEC`. + Return a pair of file descriptors ``(r, w)`` usable for reading and writing, + respectively. + + Availability: some flavors of Unix. + + .. versionadded:: 3.3 + + .. function:: posix_fallocate(fd, offset, len) Ensures that enough disk space is allocated for the file specified by *fd* diff --git a/Doc/library/packaging-misc.rst b/Doc/library/packaging-misc.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging-misc.rst @@ -0,0 +1,27 @@ +.. temporary file for modules that don't need a dedicated file yet + +:mod:`packaging.errors` --- Packaging exceptions +================================================ + +.. module:: packaging.errors + :synopsis: Packaging exceptions. + + +Provides exceptions used by the Packaging modules. Note that Packaging modules +may raise standard exceptions; in particular, SystemExit is usually raised for +errors that are obviously the end-user's fault (e.g. bad command-line arguments). + +This module is safe to use in ``from ... import *`` mode; it only exports +symbols whose names start with ``Packaging`` and end with ``Error``. + + +:mod:`packaging.manifest` --- The Manifest class +================================================ + +.. module:: packaging.manifest + :synopsis: The Manifest class, used for poking about the file system and + building lists of files. + + +This module provides the :class:`Manifest` class, used for poking about the +filesystem and building lists of files. diff --git a/Doc/library/packaging.command.rst b/Doc/library/packaging.command.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.command.rst @@ -0,0 +1,111 @@ +:mod:`packaging.command` --- Standard Packaging commands +======================================================== + +.. module:: packaging.command + :synopsis: Standard packaging commands. + + +This subpackage contains one module for each standard Packaging command, such as +:command:`build` or :command:`upload`. Each command is implemented as a +separate module, with the command name as the name of the module and of the +class defined therein. + + + +:mod:`packaging.command.cmd` --- Abstract base class for Packaging commands +=========================================================================== + +.. module:: packaging.command.cmd + :synopsis: Abstract base class for commands. + + +This module supplies the abstract base class :class:`Command`. This class is +subclassed by the modules in the packaging.command subpackage. + + +.. class:: Command(dist) + + Abstract base class for defining command classes, the "worker bees" of the + Packaging. A useful analogy for command classes is to think of them as + subroutines with local variables called *options*. The options are declared + in :meth:`initialize_options` and defined (given their final values) in + :meth:`finalize_options`, both of which must be defined by every command + class. The distinction between the two is necessary because option values + might come from the outside world (command line, config file, ...), and any + options dependent on other options must be computed after these outside + influences have been processed --- hence :meth:`finalize_options`. The body + of the subroutine, where it does all its work based on the values of its + options, is the :meth:`run` method, which must also be implemented by every + command class. + + The class constructor takes a single argument *dist*, a + :class:`~packaging.dist.Distribution` instance. + + +Creating a new Packaging command +-------------------------------- + +This section outlines the steps to create a new Packaging command. + +.. XXX the following paragraph is focused on the stdlib; expand it to document + how to write and register a command in third-party projects + +A new command lives in a module in the :mod:`packaging.command` package. There +is a sample template in that directory called :file:`command_template`. Copy +this file to a new module with the same name as the new command you're +implementing. This module should implement a class with the same name as the +module (and the command). So, for instance, to create the command +``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy +:file:`command_template` to :file:`packaging/command/peel_banana.py`, then edit +it so that it's implementing the class :class:`peel_banana`, a subclass of +:class:`Command`. It must define the following methods: + +.. method:: Command.initialize_options() + + Set default values for all the options that this command supports. Note that + these defaults may be overridden by other commands, by the setup script, by + config files, or by the command line. Thus, this is not the place to code + dependencies between options; generally, :meth:`initialize_options` + implementations are just a bunch of ``self.foo = None`` assignments. + + +.. method:: Command.finalize_options() + + Set final values for all the options that this command supports. This is + always called as late as possible, i.e. after any option assignments from the + command line or from other commands have been done. Thus, this is the place + to to code option dependencies: if *foo* depends on *bar*, then it is safe to + set *foo* from *bar* as long as *foo* still has the same value it was + assigned in :meth:`initialize_options`. + + +.. method:: Command.run() + + A command's raison d'etre: carry out the action it exists to perform, + controlled by the options initialized in :meth:`initialize_options`, + customized by other commands, the setup script, the command line, and config + files, and finalized in :meth:`finalize_options`. All terminal output and + filesystem interaction should be done by :meth:`run`. + + +Command classes may define this attribute: + + +.. attribute:: Command.sub_commands + + *sub_commands* formalizes the notion of a "family" of commands, + e.g. ``install_dist`` as the parent with sub-commands ``install_lib``, + ``install_headers``, etc. The parent of a family of commands defines + *sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name, + predicate)``, with *command_name* a string and *predicate* a function, a + string or ``None``. *predicate* is a method of the parent command that + determines whether the corresponding command is applicable in the current + situation. (E.g. ``install_headers`` is only applicable if we have any C + header files to install.) If *predicate* is ``None``, that command is always + applicable. + + *sub_commands* is usually defined at the *end* of a class, because + predicates can be methods of the class, so they must already have been + defined. The canonical example is the :command:`install_dist` command. + +.. XXX document how to add a custom command to another one's subcommands diff --git a/Doc/library/packaging.compiler.rst b/Doc/library/packaging.compiler.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.compiler.rst @@ -0,0 +1,672 @@ +:mod:`packaging.compiler` --- Compiler classes +============================================== + +.. module:: packaging.compiler + :synopsis: Compiler classes to build C/C++ extensions or libraries. + + +This subpackage contains an abstract base class representing a compiler and +concrete implementations for common compilers. The compiler classes should not +be instantiated directly, but created using the :func:`new_compiler` factory +function. Compiler types provided by Packaging are listed in +:ref:`packaging-standard-compilers`. + + +Public functions +---------------- + +.. function:: new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0) + + Factory function to generate an instance of some + :class:`~.ccompiler.CCompiler` subclass for the requested platform or + compiler type. + + If no argument is given for *plat* and *compiler*, the default compiler type + for the platform (:attr:`os.name`) will be used: ``'unix'`` for Unix and + Mac OS X, ``'msvc'`` for Windows. + + If *plat* is given, it must be one of ``'posix'``, ``'darwin'`` or ``'nt'``. + An invalid value will not raise an exception but use the default compiler + type for the current platform. + + .. XXX errors should never pass silently; this behavior is particularly + harmful when a compiler type is given as first argument + + If *compiler* is given, *plat* will be ignored, allowing you to get for + example a ``'unix'`` compiler object under Windows or an ``'msvc'`` compiler + under Unix. However, not all compiler types can be instantiated on every + platform. + + +.. function:: customize_compiler(compiler) + + Do any platform-specific customization of a CCompiler instance. Mainly + needed on Unix to plug in the information that varies across Unices and is + stored in CPython's Makefile. + + +.. function:: gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries) + + Generate linker options for searching library directories and linking with + specific libraries. *libraries* and *library_dirs* are, respectively, lists + of library names (not filenames!) and search directories. Returns a list of + command-line options suitable for use with some compiler (depending on the + two format strings passed in). + + +.. function:: gen_preprocess_options(macros, include_dirs) + + Generate C preprocessor options (:option:`-D`, :option:`-U`, :option:`-I`) as + used by at least two types of compilers: the typical Unix compiler and Visual + C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)`` + means undefine (:option:`-U`) macro *name*, and ``(name, value)`` means + define (:option:`-D`) macro *name* to *value*. *include_dirs* is just a list + of directory names to be added to the header file search path (:option:`-I`). + Returns a list of command-line options suitable for either Unix compilers or + Visual C++. + + +.. function:: get_default_compiler(osname, platform) + + Determine the default compiler to use for the given platform. + + *osname* should be one of the standard Python OS names (i.e. the ones + returned by ``os.name``) and *platform* the common value returned by + ``sys.platform`` for the platform in question. + + The default values are ``os.name`` and ``sys.platform``. + + +.. function:: set_compiler(location) + + Add or change a compiler + + +.. function:: show_compilers() + + Print list of available compilers (used by the :option:`--help-compiler` + options to :command:`build`, :command:`build_ext`, :command:`build_clib`). + + +.. _packaging-standard-compilers: + +Standard compilers +------------------ + +Concrete subclasses of :class:`~.ccompiler.CCompiler` are provided in submodules +of the :mod:`packaging.compiler` package. You do not need to import them, using +:func:`new_compiler` is the public API to use. This table documents the +standard compilers; be aware that they can be replaced by other classes on your +platform. + +=============== ======================================================== ======= +name description notes +=============== ======================================================== ======= +``'unix'`` typical Unix-style command-line C compiler [#]_ +``'msvc'`` Microsoft compiler [#]_ +``'bcpp'`` Borland C++ compiler +``'cygwin'`` Cygwin compiler (Windows port of GCC) +``'mingw32'`` Mingw32 port of GCC (same as Cygwin in no-Cygwin mode) +=============== ======================================================== ======= + + +.. [#] The Unix compiler class assumes this behavior: + + * macros defined with :option:`-Dname[=value]` + + * macros undefined with :option:`-Uname` + + * include search directories specified with :option:`-Idir` + + * libraries specified with :option:`-llib` + + * library search directories specified with :option:`-Ldir` + + * compile handled by :program:`cc` (or similar) executable with + :option:`-c` option: compiles :file:`.c` to :file:`.o` + + * link static library handled by :program:`ar` command (possibly with + :program:`ranlib`) + + * link shared library handled by :program:`cc` :option:`-shared` + + +.. [#] On Windows, extension modules typically need to be compiled with the same + compiler that was used to compile CPython (for example Microsoft Visual + Studio .NET 2003 for CPython 2.4 and 2.5). The AMD64 and Itanium + binaries are created using the Platform SDK. + + Under the hood, there are actually two different subclasses of + :class:`~.ccompiler.CCompiler` defined: one is compatible with MSVC 2005 + and 2008, the other works with older versions. This should not be a + concern for regular use of the functions in this module. + + Packaging will normally choose the right compiler, linker etc. on its + own. To override this choice, the environment variables + *DISTUTILS_USE_SDK* and *MSSdk* must be both set. *MSSdk* indicates that + the current environment has been setup by the SDK's ``SetEnv.Cmd`` + script, or that the environment variables had been registered when the + SDK was installed; *DISTUTILS_USE_SDK* indicates that the user has made + an explicit choice to override the compiler selection done by Packaging. + + .. TODO document the envvars in Doc/using and the man page + + +:mod:`packaging.compiler.ccompiler` --- CCompiler base class +============================================================ + +.. module:: packaging.compiler.ccompiler + :synopsis: Abstract CCompiler class. + + +This module provides the abstract base class for the :class:`CCompiler` +classes. A :class:`CCompiler` instance can be used for all the compile and +link steps needed to build a single project. Methods are provided to set +options for the compiler --- macro definitions, include directories, link path, +libraries and the like. + +.. class:: CCompiler([verbose=0, dry_run=0, force=0]) + + The abstract base class :class:`CCompiler` defines the interface that must be + implemented by real compiler classes. The class also has some utility + methods used by several compiler classes. + + The basic idea behind a compiler abstraction class is that each instance can + be used for all the compile/link steps in building a single project. Thus, + attributes common to all of those compile and link steps --- include + directories, macros to define, libraries to link against, etc. --- are + attributes of the compiler instance. To allow for variability in how + individual files are treated, most of those attributes may be varied on a + per-compilation or per-link basis. + + The constructor for each subclass creates an instance of the Compiler object. + Flags are *verbose* (show verbose output), *dry_run* (don't actually execute + the steps) and *force* (rebuild everything, regardless of dependencies). All + of these flags default to ``0`` (off). Note that you probably don't want to + instantiate :class:`CCompiler` or one of its subclasses directly - use the + :func:`packaging.CCompiler.new_compiler` factory function instead. + + The following methods allow you to manually alter compiler options for the + instance of the Compiler class. + + + .. method:: CCompiler.add_include_dir(dir) + + Add *dir* to the list of directories that will be searched for header + files. The compiler is instructed to search directories in the order in + which they are supplied by successive calls to :meth:`add_include_dir`. + + + .. method:: CCompiler.set_include_dirs(dirs) + + Set the list of directories that will be searched to *dirs* (a list of + strings). Overrides any preceding calls to :meth:`add_include_dir`; + subsequent calls to :meth:`add_include_dir` add to the list passed to + :meth:`set_include_dirs`. This does not affect any list of standard + include directories that the compiler may search by default. + + + .. method:: CCompiler.add_library(libname) + + Add *libname* to the list of libraries that will be included in all links + driven by this compiler object. Note that *libname* should *not* be the + name of a file containing a library, but the name of the library itself: + the actual filename will be inferred by the linker, the compiler, or the + compiler class (depending on the platform). + + The linker will be instructed to link against libraries in the order they + were supplied to :meth:`add_library` and/or :meth:`set_libraries`. It is + perfectly valid to duplicate library names; the linker will be instructed + to link against libraries as many times as they are mentioned. + + + .. method:: CCompiler.set_libraries(libnames) + + Set the list of libraries to be included in all links driven by this + compiler object to *libnames* (a list of strings). This does not affect + any standard system libraries that the linker may include by default. + + + .. method:: CCompiler.add_library_dir(dir) + + Add *dir* to the list of directories that will be searched for libraries + specified to :meth:`add_library` and :meth:`set_libraries`. The linker + will be instructed to search for libraries in the order they are supplied + to :meth:`add_library_dir` and/or :meth:`set_library_dirs`. + + + .. method:: CCompiler.set_library_dirs(dirs) + + Set the list of library search directories to *dirs* (a list of strings). + This does not affect any standard library search path that the linker may + search by default. + + + .. method:: CCompiler.add_runtime_library_dir(dir) + + Add *dir* to the list of directories that will be searched for shared + libraries at runtime. + + + .. method:: CCompiler.set_runtime_library_dirs(dirs) + + Set the list of directories to search for shared libraries at runtime to + *dirs* (a list of strings). This does not affect any standard search path + that the runtime linker may search by default. + + + .. method:: CCompiler.define_macro(name[, value=None]) + + Define a preprocessor macro for all compilations driven by this compiler + object. The optional parameter *value* should be a string; if it is not + supplied, then the macro will be defined without an explicit value and the + exact outcome depends on the compiler used (XXX true? does ANSI say + anything about this?) + + + .. method:: CCompiler.undefine_macro(name) + + Undefine a preprocessor macro for all compilations driven by this compiler + object. If the same macro is defined by :meth:`define_macro` and + undefined by :meth:`undefine_macro` the last call takes precedence + (including multiple redefinitions or undefinitions). If the macro is + redefined/undefined on a per-compilation basis (i.e. in the call to + :meth:`compile`), then that takes precedence. + + + .. method:: CCompiler.add_link_object(object) + + Add *object* to the list of object files (or analogues, such as explicitly + named library files or the output of "resource compilers") to be included + in every link driven by this compiler object. + + + .. method:: CCompiler.set_link_objects(objects) + + Set the list of object files (or analogues) to be included in every link + to *objects*. This does not affect any standard object files that the + linker may include by default (such as system libraries). + + The following methods implement methods for autodetection of compiler + options, providing some functionality similar to GNU :program:`autoconf`. + + + .. method:: CCompiler.detect_language(sources) + + Detect the language of a given file, or list of files. Uses the instance + attributes :attr:`language_map` (a dictionary), and :attr:`language_order` + (a list) to do the job. + + + .. method:: CCompiler.find_library_file(dirs, lib[, debug=0]) + + Search the specified list of directories for a static or shared library file + *lib* and return the full path to that file. If *debug* is true, look for a + debugging version (if that makes sense on the current platform). Return + ``None`` if *lib* wasn't found in any of the specified directories. + + + .. method:: CCompiler.has_function(funcname [, includes=None, include_dirs=None, libraries=None, library_dirs=None]) + + Return a boolean indicating whether *funcname* is supported on the current + platform. The optional arguments can be used to augment the compilation + environment by providing additional include files and paths and libraries and + paths. + + + .. method:: CCompiler.library_dir_option(dir) + + Return the compiler option to add *dir* to the list of directories searched for + libraries. + + + .. method:: CCompiler.library_option(lib) + + Return the compiler option to add *dir* to the list of libraries linked into the + shared library or executable. + + + .. method:: CCompiler.runtime_library_dir_option(dir) + + Return the compiler option to add *dir* to the list of directories searched for + runtime libraries. + + + .. method:: CCompiler.set_executables(**args) + + Define the executables (and options for them) that will be run to perform the + various stages of compilation. The exact set of executables that may be + specified here depends on the compiler class (via the 'executables' class + attribute), but most will have: + + +--------------+------------------------------------------+ + | attribute | description | + +==============+==========================================+ + | *compiler* | the C/C++ compiler | + +--------------+------------------------------------------+ + | *linker_so* | linker used to create shared objects and | + | | libraries | + +--------------+------------------------------------------+ + | *linker_exe* | linker used to create binary executables | + +--------------+------------------------------------------+ + | *archiver* | static library creator | + +--------------+------------------------------------------+ + + On platforms with a command line (Unix, DOS/Windows), each of these is a string + that will be split into executable name and (optional) list of arguments. + (Splitting the string is done similarly to how Unix shells operate: words are + delimited by spaces, but quotes and backslashes can override this. See + :func:`packaging.util.split_quoted`.) + + The following methods invoke stages in the build process. + + + .. method:: CCompiler.compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None]) + + Compile one or more source files. Generates object files (e.g. transforms a + :file:`.c` file to a :file:`.o` file.) + + *sources* must be a list of filenames, most likely C/C++ files, but in reality + anything that can be handled by a particular compiler and compiler class (e.g. + an ``'msvc'`` compiler` can handle resource files in *sources*). Return a list of + object filenames, one per source filename in *sources*. Depending on the + implementation, not all source files will necessarily be compiled, but all + corresponding object filenames will be returned. + + If *output_dir* is given, object files will be put under it, while retaining + their original path component. That is, :file:`foo/bar.c` normally compiles to + :file:`foo/bar.o` (for a Unix implementation); if *output_dir* is *build*, then + it would compile to :file:`build/foo/bar.o`. + + *macros*, if given, must be a list of macro definitions. A macro definition is + either a ``(name, value)`` 2-tuple or a ``(name,)`` 1-tuple. The former defines + a macro; if the value is ``None``, the macro is defined without an explicit + value. The 1-tuple case undefines a macro. Later + definitions/redefinitions/undefinitions take precedence. + + *include_dirs*, if given, must be a list of strings, the directories to add to + the default include file search path for this compilation only. + + *debug* is a boolean; if true, the compiler will be instructed to output debug + symbols in (or alongside) the object file(s). + + *extra_preargs* and *extra_postargs* are implementation-dependent. On platforms + that have the notion of a command line (e.g. Unix, DOS/Windows), they are most + likely lists of strings: extra command-line arguments to prepend/append to the + compiler command line. On other platforms, consult the implementation class + documentation. In any event, they are intended as an escape hatch for those + occasions when the abstract compiler framework doesn't cut the mustard. + + *depends*, if given, is a list of filenames that all targets depend on. If a + source file is older than any file in depends, then the source file will be + recompiled. This supports dependency tracking, but only at a coarse + granularity. + + Raises :exc:`CompileError` on failure. + + + .. method:: CCompiler.create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None]) + + Link a bunch of stuff together to create a static library file. The "bunch of + stuff" consists of the list of object files supplied as *objects*, the extra + object files supplied to :meth:`add_link_object` and/or + :meth:`set_link_objects`, the libraries supplied to :meth:`add_library` and/or + :meth:`set_libraries`, and the libraries supplied as *libraries* (if any). + + *output_libname* should be a library name, not a filename; the filename will be + inferred from the library name. *output_dir* is the directory where the library + file will be put. XXX defaults to what? + + *debug* is a boolean; if true, debugging information will be included in the + library (note that on most platforms, it is the compile step where this matters: + the *debug* flag is included here just for consistency). + + *target_lang* is the target language for which the given objects are being + compiled. This allows specific linkage time treatment of certain languages. + + Raises :exc:`LibError` on failure. + + + .. method:: CCompiler.link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a bunch of stuff together to create an executable or shared library file. + + The "bunch of stuff" consists of the list of object files supplied as *objects*. + *output_filename* should be a filename. If *output_dir* is supplied, + *output_filename* is relative to it (i.e. *output_filename* can provide + directory components if needed). + + *libraries* is a list of libraries to link against. These are library names, + not filenames, since they're translated into filenames in a platform-specific + way (e.g. *foo* becomes :file:`libfoo.a` on Unix and :file:`foo.lib` on + DOS/Windows). However, they can include a directory component, which means the + linker will look in that specific directory rather than searching all the normal + locations. + + *library_dirs*, if supplied, should be a list of directories to search for + libraries that were specified as bare library names (i.e. no directory + component). These are on top of the system default and those supplied to + :meth:`add_library_dir` and/or :meth:`set_library_dirs`. *runtime_library_dirs* + is a list of directories that will be embedded into the shared library and used + to search for other shared libraries that \*it\* depends on at run-time. (This + may only be relevant on Unix.) + + *export_symbols* is a list of symbols that the shared library will export. + (This appears to be relevant only on Windows.) + + *debug* is as for :meth:`compile` and :meth:`create_static_lib`, with the + slight distinction that it actually matters on most platforms (as opposed to + :meth:`create_static_lib`, which includes a *debug* flag mostly for form's + sake). + + *extra_preargs* and *extra_postargs* are as for :meth:`compile` (except of + course that they supply command-line arguments for the particular linker being + used). + + *target_lang* is the target language for which the given objects are being + compiled. This allows specific linkage time treatment of certain languages. + + Raises :exc:`LinkError` on failure. + + + .. method:: CCompiler.link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None]) + + Link an executable. *output_progname* is the name of the file executable, while + *objects* are a list of object filenames to link in. Other arguments are as for + the :meth:`link` method. + + + .. method:: CCompiler.link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a shared library. *output_libname* is the name of the output library, + while *objects* is a list of object filenames to link in. Other arguments are + as for the :meth:`link` method. + + + .. method:: CCompiler.link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) + + Link a shared object. *output_filename* is the name of the shared object that + will be created, while *objects* is a list of object filenames to link in. + Other arguments are as for the :meth:`link` method. + + + .. method:: CCompiler.preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None]) + + Preprocess a single C/C++ source file, named in *source*. Output will be written + to file named *output_file*, or *stdout* if *output_file* not supplied. + *macros* is a list of macro definitions as for :meth:`compile`, which will + augment the macros set with :meth:`define_macro` and :meth:`undefine_macro`. + *include_dirs* is a list of directory names that will be added to the default + list, in the same way as :meth:`add_include_dir`. + + Raises :exc:`PreprocessError` on failure. + + The following utility methods are defined by the :class:`CCompiler` class, for + use by the various concrete subclasses. + + + .. method:: CCompiler.executable_filename(basename[, strip_dir=0, output_dir='']) + + Returns the filename of the executable for the given *basename*. Typically for + non-Windows platforms this is the same as the basename, while Windows will get + a :file:`.exe` added. + + + .. method:: CCompiler.library_filename(libname[, lib_type='static', strip_dir=0, output_dir='']) + + Returns the filename for the given library name on the current platform. On Unix + a library with *lib_type* of ``'static'`` will typically be of the form + :file:`liblibname.a`, while a *lib_type* of ``'dynamic'`` will be of the form + :file:`liblibname.so`. + + + .. method:: CCompiler.object_filenames(source_filenames[, strip_dir=0, output_dir='']) + + Returns the name of the object files for the given source files. + *source_filenames* should be a list of filenames. + + + .. method:: CCompiler.shared_object_filename(basename[, strip_dir=0, output_dir='']) + + Returns the name of a shared object file for the given file name *basename*. + + + .. method:: CCompiler.execute(func, args[, msg=None, level=1]) + + Invokes :func:`packaging.util.execute` This method invokes a Python function + *func* with the given arguments *args*, after logging and taking into account + the *dry_run* flag. XXX see also. + + + .. method:: CCompiler.spawn(cmd) + + Invokes :func:`packaging.util.spawn`. This invokes an external process to run + the given command. XXX see also. + + + .. method:: CCompiler.mkpath(name[, mode=511]) + + Invokes :func:`packaging.dir_util.mkpath`. This creates a directory and any + missing ancestor directories. XXX see also. + + + .. method:: CCompiler.move_file(src, dst) + + Invokes :meth:`packaging.file_util.move_file`. Renames *src* to *dst*. XXX see + also. + + +:mod:`packaging.compiler.extension` --- The Extension class +=========================================================== + +.. module:: packaging.compiler.extension + :synopsis: Class used to represent C/C++ extension modules. + + +This module provides the :class:`Extension` class, used to represent C/C++ +extension modules. + +.. class:: Extension + + The Extension class describes a single C or C++ extension module. It accepts + the following keyword arguments in its constructor + + +------------------------+--------------------------------+---------------------------+ + | argument name | value | type | + +========================+================================+===========================+ + | *name* | the full name of the | string | + | | extension, including any | | + | | packages --- i.e. *not* a | | + | | filename or pathname, but | | + | | Python dotted name | | + +------------------------+--------------------------------+---------------------------+ + | *sources* | list of source filenames, | string | + | | relative to the distribution | | + | | root (where the setup script | | + | | lives), in Unix form (slash- | | + | | separated) for portability. | | + | | Source files may be C, C++, | | + | | SWIG (.i), platform-specific | | + | | resource files, or whatever | | + | | else is recognized by the | | + | | :command:`build_ext` command | | + | | as source for a Python | | + | | extension. | | + +------------------------+--------------------------------+---------------------------+ + | *include_dirs* | list of directories to search | string | + | | for C/C++ header files (in | | + | | Unix form for portability) | | + +------------------------+--------------------------------+---------------------------+ + | *define_macros* | list of macros to define; each | (string, string) tuple or | + | | macro is defined using a | (name, ``None``) | + | | 2-tuple ``(name, value)``, | | + | | where *value* is | | + | | either the string to define it | | + | | to or ``None`` to define it | | + | | without a particular value | | + | | (equivalent of ``#define FOO`` | | + | | in source or :option:`-DFOO` | | + | | on Unix C compiler command | | + | | line) | | + +------------------------+--------------------------------+---------------------------+ + | *undef_macros* | list of macros to undefine | string | + | | explicitly | | + +------------------------+--------------------------------+---------------------------+ + | *library_dirs* | list of directories to search | string | + | | for C/C++ libraries at link | | + | | time | | + +------------------------+--------------------------------+---------------------------+ + | *libraries* | list of library names (not | string | + | | filenames or paths) to link | | + | | against | | + +------------------------+--------------------------------+---------------------------+ + | *runtime_library_dirs* | list of directories to search | string | + | | for C/C++ libraries at run | | + | | time (for shared extensions, | | + | | this is when the extension is | | + | | loaded) | | + +------------------------+--------------------------------+---------------------------+ + | *extra_objects* | list of extra files to link | string | + | | with (e.g. object files not | | + | | implied by 'sources', static | | + | | library that must be | | + | | explicitly specified, binary | | + | | resource files, etc.) | | + +------------------------+--------------------------------+---------------------------+ + | *extra_compile_args* | any extra platform- and | string | + | | compiler-specific information | | + | | to use when compiling the | | + | | source files in 'sources'. For | | + | | platforms and compilers where | | + | | a command line makes sense, | | + | | this is typically a list of | | + | | command-line arguments, but | | + | | for other platforms it could | | + | | be anything. | | + +------------------------+--------------------------------+---------------------------+ + | *extra_link_args* | any extra platform- and | string | + | | compiler-specific information | | + | | to use when linking object | | + | | files together to create the | | + | | extension (or to create a new | | + | | static Python interpreter). | | + | | Similar interpretation as for | | + | | 'extra_compile_args'. | | + +------------------------+--------------------------------+---------------------------+ + | *export_symbols* | list of symbols to be exported | string | + | | from a shared extension. Not | | + | | used on all platforms, and not | | + | | generally necessary for Python | | + | | extensions, which typically | | + | | export exactly one symbol: | | + | | ``init`` + extension_name. | | + +------------------------+--------------------------------+---------------------------+ + | *depends* | list of files that the | string | + | | extension depends on | | + +------------------------+--------------------------------+---------------------------+ + | *language* | extension language (i.e. | string | + | | ``'c'``, ``'c++'``, | | + | | ``'objc'``). Will be detected | | + | | from the source extensions if | | + | | not provided. | | + +------------------------+--------------------------------+---------------------------+ diff --git a/Doc/library/packaging.database.rst b/Doc/library/packaging.database.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.database.rst @@ -0,0 +1,324 @@ +:mod:`packaging.database` --- Database of installed distributions +================================================================= + +.. module:: packaging.database + :synopsis: Functions to query and manipulate installed distributions. + + +This module provides an implementation of :PEP:`376`. It was originally +intended to land in :mod:`pkgutil`, but with the inclusion of Packaging in the +standard library, it was thought best to include it in a submodule of +:mod:`packaging`, leaving :mod:`pkgutil` to deal with imports. + +Installed Python distributions are represented by instances of +:class:`Distribution`, or :class:`EggInfoDistribution` for legacy egg formats. +Most functions also provide an extra argument ``use_egg_info`` to take legacy +distributions into account. + + +Classes representing installed distributions +-------------------------------------------- + +.. class:: Distribution(path) + + Class representing an installed distribution. It is different from + :class:`packaging.dist.Distribution` which holds the list of files, the + metadata and options during the run of a Packaging command. + + Instantiate with the *path* to a ``.dist-info`` directory. Instances can be + compared and sorted. Other available methods are: + + .. XXX describe how comparison works + + .. method:: get_distinfo_file(path, binary=False) + + Return a read-only file object for a file located at + :file:`{project-version}.dist-info/path}`. *path* should be a + ``'/'``-separated path relative to the ``.dist-info`` directory or an + absolute path; if it is an absolute path and doesn't start with the path + to the :file:`.dist-info` directory, a :class:`PackagingError` is raised. + + If *binary* is ``True``, the file is opened in binary mode. + + .. method:: get_resource_path(relative_path) + + .. TODO + + .. method:: list_distinfo_files(local=False) + + Return an iterator over all files located in the :file:`.dist-info` + directory. If *local* is ``True``, each returned path is transformed into + a local absolute path, otherwise the raw value found in the :file:`RECORD` + file is returned. + + .. method:: list_installed_files(local=False) + + Iterate over the files installed with the distribution and registered in + the :file:`RECORD` file and yield a tuple ``(path, md5, size)`` for each + line. If *local* is ``True``, the returned path is transformed into a + local absolute path, otherwise the raw value is returned. + + A local absolute path is an absolute path in which occurrences of ``'/'`` + have been replaced by :data:`os.sep`. + + .. method:: uses(path) + + Check whether *path* was installed by this distribution (i.e. if the path + is present in the :file:`RECORD` file). *path* can be a local absolute + path or a relative ``'/'``-separated path. Returns a boolean. + + Available attributes: + + .. attribute:: metadata + + Instance of :class:`packaging.metadata.Metadata` filled with the contents + of the :file:`{project-version}.dist-info/METADATA` file. + + .. attribute:: name + + Shortcut for ``metadata['Name']``. + + .. attribute:: version + + Shortcut for ``metadata['Version']``. + + .. attribute:: requested + + Boolean indicating whether this distribution was requested by the user of + automatically installed as a dependency. + + +.. class:: EggInfoDistribution(path) + + Class representing a legacy distribution. It is compatible with distutils' + and setuptools' :file:`.egg-info` and :file:`.egg` files and directories. + + .. FIXME should be named EggDistribution + + Instantiate with the *path* to an egg file or directory. Instances can be + compared and sorted. Other available methods are: + + .. method:: list_installed_files(local=False) + + .. method:: uses(path) + + Available attributes: + + .. attribute:: metadata + + Instance of :class:`packaging.metadata.Metadata` filled with the contents + of the :file:`{project-version}.egg-info/PKG-INFO` or + :file:`{project-version}.egg` file. + + .. attribute:: name + + Shortcut for ``metadata['Name']``. + + .. attribute:: version + + Shortcut for ``metadata['Version']``. + + +Functions to work with the database +----------------------------------- + +.. function:: get_distribution(name, use_egg_info=False, paths=None) + + Return an instance of :class:`Distribution` or :class:`EggInfoDistribution` + for the first installed distribution matching *name*. Egg distributions are + considered only if *use_egg_info* is true; if both a dist-info and an egg + file are found, the dist-info prevails. The directories to be searched are + given in *paths*, which defaults to :data:`sys.path`. Return ``None`` if no + matching distribution is found. + + .. FIXME param should be named use_egg + + +.. function:: get_distributions(use_egg_info=False, paths=None) + + Return an iterator of :class:`Distribution` instances for all installed + distributions found in *paths* (defaults to :data:`sys.path`). If + *use_egg_info* is true, also return instances of :class:`EggInfoDistribution` + for legacy distributions found. + + +.. function:: get_file_users(path) + + Return an iterator over all distributions using *path*, a local absolute path + or a relative ``'/'``-separated path. + + .. XXX does this work with prefixes or full file path only? + + +.. function:: obsoletes_distribution(name, version=None, use_egg_info=False) + + Return an iterator over all distributions that declare they obsolete *name*. + *version* is an optional argument to match only specific releases (see + :mod:`packaging.version`). If *use_egg_info* is true, legacy egg + distributions will be considered as well. + + +.. function:: provides_distribution(name, version=None, use_egg_info=False) + + Return an iterator over all distributions that declare they provide *name*. + *version* is an optional argument to match only specific releases (see + :mod:`packaging.version`). If *use_egg_info* is true, legacy egg + distributions will be considered as well. + + +Utility functions +----------------- + +.. function:: distinfo_dirname(name, version) + + Escape *name* and *version* into a filename-safe form and return the + directory name built from them, for example + :file:`{safename}-{safeversion}.dist-info.` In *name*, runs of + non-alphanumeric characters are replaced with one ``'_'``; in *version*, + spaces become dots, and runs of other non-alphanumeric characters (except + dots) a replaced by one ``'-'``. + + .. XXX wth spaces in version numbers? + +For performance purposes, the list of distributions is being internally +cached. Caching is enabled by default, but you can control it with these +functions: + +.. function:: clear_cache() + + Clear the cache. + +.. function:: disable_cache() + + Disable the cache, without clearing it. + +.. function:: enable_cache() + + Enable the internal cache, without clearing it. + + +Examples +-------- + +Print all information about a distribution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Given a path to a ``.dist-info`` distribution, we shall print out all +information that can be obtained using functions provided in this module:: + + import sys + import packaging.database + + path = input() + # first create the Distribution instance + try: + dist = packaging.database.Distribution(path) + except IOError: + sys.exit('No such distribution') + + print('Information about %r' % dist.name) + print() + + print('Files') + print('=====') + for path, md5, size in dist.list_installed_files(): + print('* Path: %s' % path) + print(' Hash %s, Size: %s bytes' % (md5, size)) + print() + + print('Metadata') + print('========') + for key, value in dist.metadata.items(): + print('%20s: %s' % (key, value)) + print() + + print('Extra') + print('=====') + if dist.requested: + print('* It was installed by user request') + else: + print('* It was installed as a dependency') + +If we save the script above as ``print_info.py``, we can use it to extract +information from a :file:`.dist-info` directory. By typing in the console: + +.. code-block:: sh + + $ echo /tmp/choxie/choxie-2.0.0.9.dist-info | python3 print_info.py + +we get the following output: + +.. code-block:: none + + Information about 'choxie' + + Files + ===== + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/truffles.py + Hash 5e052db6a478d06bad9ae033e6bc08af, Size: 111 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/chocolate.py + Hash ac56bf496d8d1d26f866235b95f31030, Size: 214 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9/choxie/__init__.py + Hash 416aab08dfa846f473129e89a7625bbc, Size: 25 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/INSTALLER + Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/METADATA + Hash 696a209967fef3c8b8f5a7bb10386385, Size: 225 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/REQUESTED + Hash d41d8cd98f00b204e9800998ecf8427e, Size: 0 bytes + * Path: ../tmp/distutils2/tests/fake_dists/choxie-2.0.0.9.dist-info/RECORD + Hash None, Size: None bytes + + Metadata + ======== + Metadata-Version: 1.2 + Name: choxie + Version: 2.0.0.9 + Platform: [] + Supported-Platform: UNKNOWN + Summary: Chocolate with a kick! + Description: UNKNOWN + Keywords: [] + Home-page: UNKNOWN + Author: UNKNOWN + Author-email: UNKNOWN + Maintainer: UNKNOWN + Maintainer-email: UNKNOWN + License: UNKNOWN + Classifier: [] + Download-URL: UNKNOWN + Obsoletes-Dist: ['truffles (<=0.8,>=0.5)', 'truffles (<=0.9,>=0.6)'] + Project-URL: [] + Provides-Dist: ['truffles (1.0)'] + Requires-Dist: ['towel-stuff (0.1)'] + Requires-Python: UNKNOWN + Requires-External: [] + + Extra + ===== + * It was installed as a dependency + + +Find out obsoleted distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Now, we take tackle a different problem, we are interested in finding out +which distributions have been obsoleted. This can be easily done as follows:: + + import packaging.database + + # iterate over all distributions in the system + for dist in packaging.database.get_distributions(): + name, version = dist.name, dist.version + # find out which distributions obsolete this name/version combination + replacements = packaging.database.obsoletes_distribution(name, version) + if replacements: + print('%r %s is obsoleted by' % (name, version), + ', '.join(repr(r.name) for r in replacements)) + +This is how the output might look like: + +.. code-block:: none + + 'strawberry' 0.6 is obsoleted by 'choxie' + 'grammar' 1.0a4 is obsoleted by 'towel-stuff' diff --git a/Doc/library/packaging.depgraph.rst b/Doc/library/packaging.depgraph.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.depgraph.rst @@ -0,0 +1,199 @@ +:mod:`packaging.depgraph` --- Dependency graph builder +====================================================== + +.. module:: packaging.depgraph + :synopsis: Graph builder for dependencies between releases. + + +This module provides the means to analyse the dependencies between various +distributions and to create a graph representing these dependency relationships. +In this document, "distribution" refers to an instance of +:class:`packaging.database.Distribution` or +:class:`packaging.database.EggInfoDistribution`. + +.. XXX terminology problem with dist vs. release: dists are installed, but deps + use releases + +.. XXX explain how to use it with dists not installed: Distribution can only be + instantiated with a path, but this module is useful for remote dist too + +.. XXX functions should accept and return iterators, not lists + + +The :class:`DependencyGraph` class +---------------------------------- + +.. class:: DependencyGraph + + Represent a dependency graph between releases. The nodes are distribution + instances; the edge model dependencies. An edge from ``a`` to ``b`` means + that ``a`` depends on ``b``. + + .. method:: add_distribution(distribution) + + Add *distribution* to the graph. + + .. method:: add_edge(x, y, label=None) + + Add an edge from distribution *x* to distribution *y* with the given + *label* (string). + + .. method:: add_missing(distribution, requirement) + + Add a missing *requirement* (string) for the given *distribution*. + + .. method:: repr_node(dist, level=1) + + Print a subgraph starting from *dist*. *level* gives the depth of the + subgraph. + + Direct access to the graph nodes and edges is provided through these + attributes: + + .. attribute:: adjacency_list + + Dictionary mapping distributions to a list of ``(other, label)`` tuples + where ``other`` is a distribution and the edge is labeled with ``label`` + (i.e. the version specifier, if such was provided). + + .. attribute:: reverse_list + + Dictionary mapping distributions to a list of predecessors. This allows + efficient traversal. + + .. attribute:: missing + + Dictionary mapping distributions to a list of requirements that were not + provided by any distribution. + + +Auxiliary functions +------------------- + +.. function:: dependent_dists(dists, dist) + + Recursively generate a list of distributions from *dists* that are dependent + on *dist*. + + .. XXX what does member mean here: "dist is a member of *dists* for which we + are interested" + +.. function:: generate_graph(dists) + + Generate a :class:`DependencyGraph` from the given list of distributions. + + .. XXX make this alternate constructor a DepGraph classmethod or rename; + 'generate' can suggest it creates a file or an image, use 'make' + +.. function:: graph_to_dot(graph, f, skip_disconnected=True) + + Write a DOT output for the graph to the file-like object *f*. + + If *skip_disconnected* is true, all distributions that are not dependent on + any other distribution are skipped. + + .. XXX why is this not a DepGraph method? + + +Example Usage +------------- + +Depict all dependenciess in the system +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +First, we shall generate a graph of all the distributions on the system +and then create an image out of it using the tools provided by +`Graphviz `_:: + + from packaging.database import get_distributions + from packaging.depgraph import generate_graph + + dists = list(get_distributions()) + graph = generate_graph(dists) + +It would be interesting to print out the missing requirements. This can be done +as follows:: + + for dist, reqs in graph.missing.items(): + if reqs: + reqs = ' ,'.join(repr(req) for req in reqs) + print('Missing dependencies for %r: %s' % (dist.name, reqs)) + +Example output is: + +.. code-block:: none + + Missing dependencies for 'TurboCheetah': 'Cheetah' + Missing dependencies for 'TurboGears': 'ConfigObj', 'DecoratorTools', 'RuleDispatch' + Missing dependencies for 'jockey': 'PyKDE4.kdecore', 'PyKDE4.kdeui', 'PyQt4.QtCore', 'PyQt4.QtGui' + Missing dependencies for 'TurboKid': 'kid' + Missing dependencies for 'TurboJson: 'DecoratorTools', 'RuleDispatch' + +Now, we proceed with generating a graphical representation of the graph. First +we write it to a file, and then we generate a PNG image using the +:program:`dot` command-line tool:: + + from packaging.depgraph import graph_to_dot + with open('output.dot', 'w') as f: + # only show the interesting distributions, skipping the disconnected ones + graph_to_dot(graph, f, skip_disconnected=True) + +We can create the final picture using: + +.. code-block:: sh + + $ dot -Tpng output.dot > output.png + +An example result is: + +.. figure:: depgraph-output.png + :alt: Example PNG output from packaging.depgraph and dot + +If you want to include egg distributions as well, then the code requires only +one change, namely the line:: + + dists = list(packaging.database.get_distributions()) + +has to be replaced with:: + + dists = list(packaging.database.get_distributions(use_egg_info=True)) + +On many platforms, a richer graph is obtained because at the moment most +distributions are provided in the egg rather than the new standard +``.dist-info`` format. + +.. XXX missing image + + An example of a more involved graph for illustrative reasons can be seen + here: + + .. image:: depgraph_big.png + + +List all dependent distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We will list all distributions that are dependent on some given distibution. +This time, egg distributions will be considered as well:: + + import sys + from packaging.database import get_distribution, get_distributions + from packaging.depgraph import dependent_dists + + dists = list(get_distributions(use_egg_info=True)) + dist = get_distribution('bacon', use_egg_info=True) + if dist is None: + sys.exit('No such distribution in the system') + + deps = dependent_dists(dists, dist) + deps = ', '.join(repr(x.name) for x in deps) + print('Distributions depending on %r: %s' % (dist.name, deps)) + +And this is example output: + +.. with the dependency relationships as in the previous section + (depgraph_big) + +.. code-block:: none + + Distributions depending on 'bacon': 'towel-stuff', 'choxie', 'grammar' diff --git a/Doc/library/packaging.dist.rst b/Doc/library/packaging.dist.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.dist.rst @@ -0,0 +1,102 @@ +:mod:`packaging.dist` --- The Distribution class +================================================ + +.. module:: packaging.dist + :synopsis: Core Distribution class. + + +This module provides the :class:`Distribution` class, which represents the +module distribution being built/packaged/distributed/installed. + +.. class:: Distribution(arguments) + + A :class:`Distribution` describes how to build, package, distribute and + install a Python project. + + The arguments accepted by the constructor are laid out in the following + table. Some of them will end up in a metadata object, the rest will become + data attributes of the :class:`Distribution` instance. + + .. TODO improve constructor to take a Metadata object + named params? + (i.e. Distribution(metadata, cmdclass, py_modules, etc) + .. TODO also remove obsolete(?) script_name, etc. parameters? see what + py2exe and other tools need + + +--------------------+--------------------------------+-------------------------------------------------------------+ + | argument name | value | type | + +====================+================================+=============================================================+ + | *name* | The name of the project | string | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *version* | The version number of the | See :mod:`packaging.version` | + | | release | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *summary* | A single line describing the | a string | + | | project | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *description* | Longer description of the | a string | + | | project | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *author* | The name of the project author | a string | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *author_email* | The email address of the | a string | + | | project author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *maintainer* | The name of the current | a string | + | | maintainer, if different from | | + | | the author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *maintainer_email* | The email address of the | | + | | current maintainer, if | | + | | different from the author | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *home_page* | A URL for the proejct | a URL | + | | (homepage) | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *download_url* | A URL to download the project | a URL | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *packages* | A list of Python packages that | a list of strings | + | | packaging will manipulate | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *py_modules* | A list of Python modules that | a list of strings | + | | packaging will manipulate | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *scripts* | A list of standalone scripts | a list of strings | + | | to be built and installed | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *ext_modules* | A list of Python extensions to | A list of instances of | + | | be built | :class:`packaging.compiler.extension.Extension` | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *classifiers* | A list of categories for the | The list of available | + | | distribution | categorizations is at | + | | | http://pypi.python.org/pypi?:action=list_classifiers. | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *distclass* | the :class:`Distribution` | A subclass of | + | | class to use | :class:`packaging.dist.Distribution` | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *script_name* | The name of the setup.py | a string | + | | script - defaults to | | + | | ``sys.argv[0]`` | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *script_args* | Arguments to supply to the | a list of strings | + | | setup script | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *options* | default options for the setup | a string | + | | script | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *license* | The license for the | a string; should be used when there is no suitable License | + | | distribution | classifier, or to specify a classifier | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *keywords* | Descriptive keywords | a list of strings; used by catalogs | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *platforms* | Platforms compatible with this | a list of strings; should be used when there is no | + | | distribution | suitable Platform classifier | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *cmdclass* | A mapping of command names to | a dictionary | + | | :class:`Command` subclasses | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *data_files* | A list of data files to | a list | + | | install | | + +--------------------+--------------------------------+-------------------------------------------------------------+ + | *package_dir* | A mapping of Python packages | a dictionary | + | | to directory names | | + +--------------------+--------------------------------+-------------------------------------------------------------+ diff --git a/Doc/library/packaging.fancy_getopt.rst b/Doc/library/packaging.fancy_getopt.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.fancy_getopt.rst @@ -0,0 +1,75 @@ +:mod:`packaging.fancy_getopt` --- Wrapper around the getopt module +================================================================== + +.. module:: packaging.fancy_getopt + :synopsis: Additional getopt functionality. + + +.. warning:: + This module is deprecated and will be replaced with :mod:`optparse`. + +This module provides a wrapper around the standard :mod:`getopt` module that +provides the following additional features: + +* short and long options are tied together + +* options have help strings, so :func:`fancy_getopt` could potentially create a + complete usage summary + +* options set attributes of a passed-in object + +* boolean options can have "negative aliases" --- e.g. if :option:`--quiet` is + the "negative alias" of :option:`--verbose`, then :option:`--quiet` on the + command line sets *verbose* to false. + +.. function:: fancy_getopt(options, negative_opt, object, args) + + Wrapper function. *options* is a list of ``(long_option, short_option, + help_string)`` 3-tuples as described in the constructor for + :class:`FancyGetopt`. *negative_opt* should be a dictionary mapping option names + to option names, both the key and value should be in the *options* list. + *object* is an object which will be used to store values (see the :meth:`getopt` + method of the :class:`FancyGetopt` class). *args* is the argument list. Will use + ``sys.argv[1:]`` if you pass ``None`` as *args*. + + +.. class:: FancyGetopt([option_table=None]) + + The option_table is a list of 3-tuples: ``(long_option, short_option, + help_string)`` + + If an option takes an argument, its *long_option* should have ``'='`` appended; + *short_option* should just be a single character, no ``':'`` in any case. + *short_option* should be ``None`` if a *long_option* doesn't have a + corresponding *short_option*. All option tuples must have long options. + +The :class:`FancyGetopt` class provides the following methods: + + +.. method:: FancyGetopt.getopt([args=None, object=None]) + + Parse command-line options in args. Store as attributes on *object*. + + If *args* is ``None`` or not supplied, uses ``sys.argv[1:]``. If *object* is + ``None`` or not supplied, creates a new :class:`OptionDummy` instance, stores + option values there, and returns a tuple ``(args, object)``. If *object* is + supplied, it is modified in place and :func:`getopt` just returns *args*; in + both cases, the returned *args* is a modified copy of the passed-in *args* list, + which is left untouched. + + .. TODO and args returned are? + + +.. method:: FancyGetopt.get_option_order() + + Returns the list of ``(option, value)`` tuples processed by the previous run of + :meth:`getopt` Raises :exc:`RuntimeError` if :meth:`getopt` hasn't been called + yet. + + +.. method:: FancyGetopt.generate_help([header=None]) + + Generate help text (a list of strings, one per suggested line of output) from + the option table for this :class:`FancyGetopt` object. + + If supplied, prints the supplied *header* at the top of the help. diff --git a/Doc/library/packaging.install.rst b/Doc/library/packaging.install.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.install.rst @@ -0,0 +1,112 @@ +:mod:`packaging.install` --- Installation tools +=============================================== + +.. module:: packaging.install + :synopsis: Download and installation building blocks + + +Packaging provides a set of tools to deal with downloads and installation of +distributions. Their role is to download the distribution from indexes, resolve +the dependencies, and provide a safe way to install distributions. An operation +that fails will cleanly roll back, not leave half-installed distributions on the +system. Here's the basic process followed: + +#. Move all distributions that will be removed to a temporary location. + +#. Install all the distributions that will be installed in a temporary location. + +#. If the installation fails, move the saved distributions back to their + location and delete the installed distributions. + +#. Otherwise, move the installed distributions to the right location and delete + the temporary locations. + +This is a higher-level module built on :mod:`packaging.database` and +:mod:`packaging.pypi`. + + +Public functions +---------------- + +.. function:: get_infos(requirements, index=None, installed=None, \ + prefer_final=True) + + Return information about what's going to be installed and upgraded. + *requirements* is a string string containing the requirements for this + project, for example ``'FooBar 1.1'`` or ``'BarBaz (<1.2)'``. + + .. XXX are requirements comma-separated? + + If you want to use another index than the main PyPI, give its URI as *index* + argument. + + *installed* is a list of already installed distributions used to find + satisfied dependencies, obsoleted distributions and eventual conflicts. + + By default, alpha, beta and candidate versions are not picked up. Set + *prefer_final* to false to accept them too. + + The results are returned in a dictionary containing all the information + needed to perform installation of the requirements with the + :func:`install_from_infos` function: + + >>> get_install_info("FooBar (<=1.2)") + {'install': [], 'remove': [], 'conflict': []} + + .. TODO should return tuple or named tuple, not dict + .. TODO use "predicate" or "requirement" consistently in version and here + .. FIXME "info" cannot be plural in English, s/infos/info/ + + +.. function:: install(project) + + +.. function:: install_dists(dists, path, paths=None) + + Safely install all distributions provided in *dists* into *path*. *paths* is + a list of paths where already-installed distributions will be looked for to + find satisfied dependencies and conflicts (default: :data:`sys.path`). + Returns a list of installed dists. + + .. FIXME dists are instances of what? + + +.. function:: install_from_infos(install_path=None, install=[], remove=[], \ + conflicts=[], paths=None) + + Safely install and remove given distributions. This function is designed to + work with the return value of :func:`get_infos`: *install*, *remove* and + *conflicts* should be list of distributions returned by :func:`get_infos`. + If *install* is not empty, *install_path* must be given to specify the path + where the distributions should be installed. *paths* is a list of paths + where already-installed distributions will be looked for (default: + :data:`sys.path`). + + This function is a very basic installer; if *conflicts* is not empty, the + system will be in a conflicting state after the function completes. It is a + building block for more sophisticated installers with conflict resolution + systems. + + .. TODO document typical value for install_path + .. TODO document integration with default schemes, esp. user site-packages + + +.. function:: install_local_project(path) + + Install a distribution from a source directory, which must contain either a + Packaging-compliant :file:`setup.cfg` file or a legacy Distutils + :file:`setup.py` script (in which case Distutils will be used under the hood + to perform the installation). + + +.. function:: remove(project_name, paths=None, auto_confirm=True) + + Remove one distribution from the system. + + .. FIXME this is the only function using "project" instead of dist/release + +.. + Example usage + -------------- + + Get the scheme of what's gonna be installed if we install "foobar": diff --git a/Doc/library/packaging.metadata.rst b/Doc/library/packaging.metadata.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.metadata.rst @@ -0,0 +1,122 @@ +:mod:`packaging.metadata` --- Metadata handling +=============================================== + +.. module:: packaging.metadata + :synopsis: Class holding the metadata of a release. + + +.. TODO use sphinx-autogen to generate basic doc from the docstrings + +.. class:: Metadata + + This class can read and write metadata files complying with any of the + defined versions: 1.0 (:PEP:`241`), 1.1 (:PEP:`314`) and 1.2 (:PEP:`345`). It + implements methods to parse Metadata files and write them, and a mapping + interface to its contents. + + The :PEP:`345` implementation supports the micro-language for the environment + markers, and displays warnings when versions that are supposed to be + :PEP:`386`-compliant are violating the specification. + + +Reading metadata +---------------- + +The :class:`Metadata` class can be instantiated +with the path of the metadata file, and provides a dict-like interface to the +values:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata('PKG-INFO') + >>> metadata.keys()[:5] + ('Metadata-Version', 'Name', 'Version', 'Platform', 'Supported-Platform') + >>> metadata['Name'] + 'CLVault' + >>> metadata['Version'] + '0.5' + >>> metadata['Requires-Dist'] + ["pywin32; sys.platform == 'win32'", "Sphinx"] + + +The fields that support environment markers can be automatically ignored if +the object is instantiated using the ``platform_dependent`` option. +:class:`Metadata` will interpret in this case +the markers and will automatically remove the fields that are not compliant +with the running environment. Here's an example under Mac OS X. The win32 +dependency we saw earlier is ignored:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata('PKG-INFO', platform_dependent=True) + >>> metadata['Requires-Dist'] + ['Sphinx'] + + +If you want to provide your own execution context, let's say to test the +metadata under a particular environment that is not the current environment, +you can provide your own values in the ``execution_context`` option, which +is the dict that may contain one or more keys of the context the micro-language +expects. + +Here's an example, simulating a win32 environment:: + + >>> from packaging.metadata import Metadata + >>> context = {'sys.platform': 'win32'} + >>> metadata = Metadata('PKG-INFO', platform_dependent=True, + ... execution_context=context) + ... + >>> metadata['Requires-Dist'] = ["pywin32; sys.platform == 'win32'", + ... "Sphinx"] + ... + >>> metadata['Requires-Dist'] + ['pywin32', 'Sphinx'] + + +Writing metadata +---------------- + +Writing metadata can be done using the ``write`` method:: + + >>> metadata.write('/to/my/PKG-INFO') + +The class will pick the best version for the metadata, depending on the values +provided. If all the values provided exist in all versions, the class will +use :attr:`PKG_INFO_PREFERRED_VERSION`. It is set by default to 1.0, the most +widespread version. + + +Conflict checking and best version +---------------------------------- + +Some fields in :PEP:`345` have to comply with the version number specification +defined in :PEP:`386`. When they don't comply, a warning is emitted:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata() + >>> metadata['Requires-Dist'] = ['Funky (Groovie)'] + "Funky (Groovie)" is not a valid predicate + >>> metadata['Requires-Dist'] = ['Funky (1.2)'] + +See also :mod:`packaging.version`. + + +.. TODO talk about check() + + +:mod:`packaging.markers` --- Environment markers +================================================ + +.. module:: packaging.markers + :synopsis: Micro-language for environment markers + + +This is an implementation of environment markers `as defined in PEP 345 +`_. It is used +for some metadata fields. + +.. function:: interpret(marker, execution_context=None) + + Interpret a marker and return a boolean result depending on the environment. + Example: + + >>> interpret("python_version > '1.0'") + True diff --git a/Doc/library/packaging.pypi.dist.rst b/Doc/library/packaging.pypi.dist.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.dist.rst @@ -0,0 +1,114 @@ +:mod:`packaging.pypi.dist` --- Classes representing query results +================================================================= + +.. module:: packaging.pypi.dist + :synopsis: Classes representing the results of queries to indexes. + + +Information coming from the indexes is held in instances of the classes defined +in this module. + +Keep in mind that each project (eg. FooBar) can have several releases +(eg. 1.1, 1.2, 1.3), and each of these releases can be provided in multiple +distributions (eg. a source distribution, a binary one, etc). + + +ReleaseInfo +----------- + +Each release has a project name, version, metadata, and related distributions. + +This information is stored in :class:`ReleaseInfo` +objects. + +.. class:: ReleaseInfo + + +DistInfo +--------- + +:class:`DistInfo` is a simple class that contains +information related to distributions; mainly the URLs where distributions +can be found. + +.. class:: DistInfo + + +ReleasesList +------------ + +The :mod:`~packaging.pypi.dist` module provides a class which works +with lists of :class:`ReleaseInfo` classes; +used to filter and order results. + +.. class:: ReleasesList + + +Example usage +------------- + +Build a list of releases and order them +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assuming we have a list of releases:: + + >>> from packaging.pypi.dist import ReleasesList, ReleaseInfo + >>> fb10 = ReleaseInfo("FooBar", "1.0") + >>> fb11 = ReleaseInfo("FooBar", "1.1") + >>> fb11a = ReleaseInfo("FooBar", "1.1a1") + >>> ReleasesList("FooBar", [fb11, fb11a, fb10]) + >>> releases.sort_releases() + >>> releases.get_versions() + ['1.1', '1.1a1', '1.0'] + >>> releases.add_release("1.2a1") + >>> releases.get_versions() + ['1.1', '1.1a1', '1.0', '1.2a1'] + >>> releases.sort_releases() + ['1.2a1', '1.1', '1.1a1', '1.0'] + >>> releases.sort_releases(prefer_final=True) + >>> releases.get_versions() + ['1.1', '1.0', '1.2a1', '1.1a1'] + + +Add distribution related information to releases +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It's easy to add distribution information to releases:: + + >>> from packaging.pypi.dist import ReleasesList, ReleaseInfo + >>> r = ReleaseInfo("FooBar", "1.0") + >>> r.add_distribution("sdist", url="http://example.org/foobar-1.0.tar.gz") + >>> r.dists + {'sdist': FooBar 1.0 sdist} + >>> r['sdist'].url + {'url': 'http://example.org/foobar-1.0.tar.gz', 'hashname': None, 'hashval': + None, 'is_external': True} + + +Getting attributes from the dist objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To abstract querying information returned from the indexes, attributes and +release information can be retrieved directly from dist objects. + +For instance, if you have a release instance that does not contain the metadata +attribute, it can be fetched by using the "fetch_metadata" method:: + + >>> r = Release("FooBar", "1.1") + >>> print r.metadata + None # metadata field is actually set to "None" + >>> r.fetch_metadata() + + +.. XXX add proper roles to these constructs + + +It's possible to retrieve a project's releases (`fetch_releases`), +metadata (`fetch_metadata`) and distributions (`fetch_distributions`) using +a similar work flow. + +.. XXX what is possible? + +Internally, this is possible because while retrieving information about +projects, releases or distributions, a reference to the client used is +stored which can be accessed using the objects `_index` attribute. diff --git a/Doc/library/packaging.pypi.rst b/Doc/library/packaging.pypi.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.rst @@ -0,0 +1,53 @@ +:mod:`packaging.pypi` --- Interface to projects indexes +======================================================= + +.. module:: packaging.pypi + :synopsis: Low-level and high-level APIs to query projects indexes. + + +Packaging queries PyPI to get information about projects or download them. The +low-level facilities used internally are also part of the public API designed to +be used by other tools. + +The :mod:`packaging.pypi` package provides those facilities, which can be +used to access information about Python projects registered at indexes, the +main one being PyPI, located ad http://pypi.python.org/. + +There is two ways to retrieve data from these indexes: a screen-scraping +interface called the "simple API", and XML-RPC. The first one uses HTML pages +located under http://pypi.python.org/simple/, the second one makes XML-RPC +requests to http://pypi.python.org/pypi/. All functions and classes also work +with other indexes such as mirrors, which typically implement only the simple +interface. + +Packaging provides a class that wraps both APIs to provide full query and +download functionality: :class:`packaging.pypi.client.ClientWrapper`. If you +want more control, you can use the underlying classes +:class:`packaging.pypi.simple.Crawler` and :class:`packaging.pypi.xmlrpc.Client` +to connect to one specific interface. + + +:mod:`packaging.pypi.client` --- High-level query API +===================================================== + +.. module:: packaging.pypi.client + :synopsis: Wrapper around :mod;`packaging.pypi.xmlrpc` and + :mod:`packaging.pypi.simple` to query indexes. + + +This module provides a high-level API to query indexes and search +for releases and distributions. The aim of this module is to choose the best +way to query the API automatically, either using XML-RPC or the simple index, +with a preference toward the latter. + +.. class:: ClientWrapper + + Instances of this class will use the simple interface or XML-RPC requests to + query indexes and return :class:`packaging.pypi.dist.ReleaseInfo` and + :class:`packaging.pypi.dist.ReleasesList` objects. + + .. method:: find_projects + + .. method:: get_release + + .. method:: get_releases diff --git a/Doc/library/packaging.pypi.simple.rst b/Doc/library/packaging.pypi.simple.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.simple.rst @@ -0,0 +1,157 @@ +:mod:`packaging.pypi.simple` --- Crawler using the PyPI "simple" interface +========================================================================== + +.. module:: packaging.pypi.simple + :synopsis: Crawler using the screen-scraping "simple" interface to fetch info + and distributions. + + +`packaging.pypi.simple` can process Python Package Indexes and provides +useful information about distributions. It also can crawl local indexes, for +instance. + +You should use `packaging.pypi.simple` for: + + * Search distributions by name and versions. + * Process index external pages. + * Download distributions by name and versions. + +And should not be used for: + + * Things that will end up in too long index processing (like "finding all + distributions with a specific version, no matters the name") + + +API +--- + +.. class:: Crawler + + +Usage Exemples +--------------- + +To help you understand how using the `Crawler` class, here are some basic +usages. + +Request the simple index to get a specific distribution +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Supposing you want to scan an index to get a list of distributions for +the "foobar" project. You can use the "get_releases" method for that. +The get_releases method will browse the project page, and return +:class:`ReleaseInfo` objects for each found link that rely on downloads. :: + + >>> from packaging.pypi.simple import Crawler + >>> crawler = Crawler() + >>> crawler.get_releases("FooBar") + [, ] + + +Note that you also can request the client about specific versions, using version +specifiers (described in `PEP 345 +`_):: + + >>> client.get_releases("FooBar < 1.2") + [, ] + + +`get_releases` returns a list of :class:`ReleaseInfo`, but you also can get the +best distribution that fullfil your requirements, using "get_release":: + + >>> client.get_release("FooBar < 1.2") + + + +Download distributions +^^^^^^^^^^^^^^^^^^^^^^ + +As it can get the urls of distributions provided by PyPI, the `Crawler` +client also can download the distributions and put it for you in a temporary +destination:: + + >>> client.download("foobar") + /tmp/temp_dir/foobar-1.2.tar.gz + + +You also can specify the directory you want to download to:: + + >>> client.download("foobar", "/path/to/my/dir") + /path/to/my/dir/foobar-1.2.tar.gz + + +While downloading, the md5 of the archive will be checked, if not matches, it +will try another time, then if fails again, raise `MD5HashDoesNotMatchError`. + +Internally, that's not the Crawler which download the distributions, but the +`DistributionInfo` class. Please refer to this documentation for more details. + + +Following PyPI external links +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default behavior for packaging is to *not* follow the links provided +by HTML pages in the "simple index", to find distributions related +downloads. + +It's possible to tell the PyPIClient to follow external links by setting the +`follow_externals` attribute, on instantiation or after:: + + >>> client = Crawler(follow_externals=True) + +or :: + + >>> client = Crawler() + >>> client.follow_externals = True + + +Working with external indexes, and mirrors +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The default `Crawler` behavior is to rely on the Python Package index stored +on PyPI (http://pypi.python.org/simple). + +As you can need to work with a local index, or private indexes, you can specify +it using the index_url parameter:: + + >>> client = Crawler(index_url="file://filesystem/path/") + +or :: + + >>> client = Crawler(index_url="http://some.specific.url/") + + +You also can specify mirrors to fallback on in case the first index_url you +provided doesnt respond, or not correctly. The default behavior for +`Crawler` is to use the list provided by Python.org DNS records, as +described in the :PEP:`381` about mirroring infrastructure. + +If you don't want to rely on these, you could specify the list of mirrors you +want to try by specifying the `mirrors` attribute. It's a simple iterable:: + + >>> mirrors = ["http://first.mirror","http://second.mirror"] + >>> client = Crawler(mirrors=mirrors) + + +Searching in the simple index +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It's possible to search for projects with specific names in the package index. +Assuming you want to find all projects containing the "distutils" keyword:: + + >>> c.search_projects("distutils") + [, , , , , , ] + + +You can also search the projects starting with a specific text, or ending with +that text, using a wildcard:: + + >>> c.search_projects("distutils*") + [, , ] + + >>> c.search_projects("*distutils") + [, , , , ] diff --git a/Doc/library/packaging.pypi.xmlrpc.rst b/Doc/library/packaging.pypi.xmlrpc.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.pypi.xmlrpc.rst @@ -0,0 +1,143 @@ +:mod:`packaging.pypi.xmlrpc` --- Crawler using the PyPI XML-RPC interface +========================================================================= + +.. module:: packaging.pypi.xmlrpc + :synopsis: Client using XML-RPC requests to fetch info and distributions. + + +Indexes can be queried using XML-RPC calls, and Packaging provides a simple +way to interface with XML-RPC. + +You should **use** XML-RPC when: + +* Searching the index for projects **on other fields than project + names**. For instance, you can search for projects based on the + author_email field. +* Searching all the versions that have existed for a project. +* you want to retrieve METADATAs information from releases or + distributions. + + +You should **avoid using** XML-RPC method calls when: + +* Retrieving the last version of a project +* Getting the projects with a specific name and version. +* The simple index can match your needs + + +When dealing with indexes, keep in mind that the index queries will always +return you :class:`packaging.pypi.dist.ReleaseInfo` and +:class:`packaging.pypi.dist.ReleasesList` objects. + +Some methods here share common APIs with the one you can find on +:class:`packaging.pypi.simple`, internally, :class:`packaging.pypi.client` +is inherited by :class:`Client` + + +API +--- + +.. class:: Client + + +Usage examples +-------------- + +Use case described here are use case that are not common to the other clients. +If you want to see all the methods, please refer to API or to usage examples +described in :class:`packaging.pypi.client.Client` + + +Finding releases +^^^^^^^^^^^^^^^^ + +It's a common use case to search for "things" within the index. We can +basically search for projects by their name, which is the most used way for +users (eg. "give me the last version of the FooBar project"). + +This can be accomplished using the following syntax:: + + >>> client = xmlrpc.Client() + >>> client.get_release("Foobar (<= 1.3)) + + >>> client.get_releases("FooBar (<= 1.3)") + [FooBar 1.1, FooBar 1.1.1, FooBar 1.2, FooBar 1.2.1] + + +And we also can find for specific fields:: + + >>> client.search_projects(field=value) + + +You could specify the operator to use, default is "or":: + + >>> client.search_projects(field=value, operator="and") + + +The specific fields you can search are: + +* name +* version +* author +* author_email +* maintainer +* maintainer_email +* home_page +* license +* summary +* description +* keywords +* platform +* download_url + + +Getting metadata information +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +XML-RPC is a prefered way to retrieve metadata information from indexes. +It's really simple to do so:: + + >>> client = xmlrpc.Client() + >>> client.get_metadata("FooBar", "1.1") + + + +Assuming we already have a :class:`packaging.pypi.ReleaseInfo` object defined, +it's possible to pass it to the xmlrpc client to retrieve and complete its +metadata:: + + >>> foobar11 = ReleaseInfo("FooBar", "1.1") + >>> client = xmlrpc.Client() + >>> returned_release = client.get_metadata(release=foobar11) + >>> returned_release + + + +Get all the releases of a project +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To retrieve all the releases for a project, you can build them using +`get_releases`:: + + >>> client = xmlrpc.Client() + >>> client.get_releases("FooBar") + [, , ] + + +Get information about distributions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Indexes have information about projects, releases **and** distributions. +If you're not familiar with those, please refer to the documentation of +:mod:`packaging.pypi.dist`. + +It's possible to retrieve information about distributions, e.g "what are the +existing distributions for this release ? How to retrieve them ?":: + + >>> client = xmlrpc.Client() + >>> release = client.get_distributions("FooBar", "1.1") + >>> release.dists + {'sdist': , 'bdist': } + +As you see, this does not return a list of distributions, but a release, +because a release can be used like a list of distributions. diff --git a/Doc/library/packaging.rst b/Doc/library/packaging.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.rst @@ -0,0 +1,78 @@ +:mod:`packaging` --- Packaging support +====================================== + +.. module:: packaging + :synopsis: Packaging system and building blocks for other packaging systems. +.. sectionauthor:: Fred L. Drake, Jr. , distutils and packaging + contributors + + +The :mod:`packaging` package provides support for building, packaging, +distributing and installing additional projects into a Python installation. +Projects may include Python modules, extension modules, packages and scripts. +:mod:`packaging` also provides building blocks for other packaging systems +that are not tied to the command system. + +This manual is the reference documentation for those standalone building +blocks and for extending Packaging. If you're looking for the user-centric +guides to install a project or package your own code, head to `See also`__. + + +Building blocks +--------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging-misc + packaging.version + packaging.metadata + packaging.database + packaging.depgraph + packaging.pypi + packaging.pypi.dist + packaging.pypi.simple + packaging.pypi.xmlrpc + packaging.install + + +The command machinery +--------------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging.dist + packaging.command + packaging.compiler + packaging.fancy_getopt + + +Other utilities +---------------- + +.. toctree:: + :maxdepth: 2 + :numbered: + + packaging.util + packaging.tests.pypi_server + +.. XXX missing: compat config create (dir_util) run pypi.{base,mirrors} + + +.. __: + +.. seealso:: + + :ref:`packaging-index` + The manual for developers of Python projects who want to package and + distribute them. This describes how to use :mod:`packaging` to make + projects easily found and added to an existing Python installation. + + :ref:`packaging-install-index` + A user-centered manual which includes information on adding projects + into an existing Python installation. You do not need to be a Python + programmer to read this manual. diff --git a/Doc/library/packaging.tests.pypi_server.rst b/Doc/library/packaging.tests.pypi_server.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.tests.pypi_server.rst @@ -0,0 +1,105 @@ +:mod:`packaging.tests.pypi_server` --- PyPI mock server +======================================================= + +.. module:: packaging.tests.pypi_server + :synopsis: Mock server used to test PyPI-related modules and commands. + + +When you are testing code that works with Packaging, you might find these tools +useful. + + +The mock server +--------------- + +.. class:: PyPIServer + + PyPIServer is a class that implements an HTTP server running in a separate + thread. All it does is record the requests for further inspection. The recorded + data is available under ``requests`` attribute. The default + HTTP response can be overridden with the ``default_response_status``, + ``default_response_headers`` and ``default_response_data`` attributes. + + By default, when accessing the server with urls beginning with `/simple/`, + the server also record your requests, but will look for files under + the `/tests/pypiserver/simple/` path. + + You can tell the sever to serve static files for other paths. This could be + accomplished by using the `static_uri_paths` parameter, as below:: + + server = PyPIServer(static_uri_paths=["first_path", "second_path"]) + + + You need to create the content that will be served under the + `/tests/pypiserver/default` path. If you want to serve content from another + place, you also can specify another filesystem path (which needs to be under + `tests/pypiserver/`. This will replace the default behavior of the server, and + it will not serve content from the `default` dir :: + + server = PyPIServer(static_filesystem_paths=["path/to/your/dir"]) + + + If you just need to add some paths to the existing ones, you can do as shown, + keeping in mind that the server will always try to load paths in reverse order + (e.g here, try "another/super/path" then the default one) :: + + server = PyPIServer(test_static_path="another/super/path") + server = PyPIServer("another/super/path") + # or + server.static_filesystem_paths.append("another/super/path") + + + As a result of what, in your tests, while you need to use the PyPIServer, in + order to isolates the test cases, the best practice is to place the common files + in the `default` folder, and to create a directory for each specific test case:: + + server = PyPIServer(static_filesystem_paths = ["default", "test_pypi_server"], + static_uri_paths=["simple", "external"]) + + +Base class and decorator for tests +---------------------------------- + +.. class:: PyPIServerTestCase + + ``PyPIServerTestCase`` is a test case class with setUp and tearDown methods that + take care of a single PyPIServer instance attached as a ``pypi`` attribute on + the test class. Use it as one of the base classes in your test case:: + + + class UploadTestCase(PyPIServerTestCase): + + def test_something(self): + cmd = self.prepare_command() + cmd.ensure_finalized() + cmd.repository = self.pypi.full_address + cmd.run() + + environ, request_data = self.pypi.requests[-1] + self.assertEqual(request_data, EXPECTED_REQUEST_DATA) + + +.. decorator:: use_pypi_server + + You also can use a decorator for your tests, if you do not need the same server + instance along all you test case. So, you can specify, for each test method, + some initialisation parameters for the server. + + For this, you need to add a `server` parameter to your method, like this:: + + class SampleTestCase(TestCase): + + @use_pypi_server() + def test_something(self, server): + ... + + + The decorator will instantiate the server for you, and run and stop it just + before and after your method call. You also can pass the server initializer, + just like this:: + + class SampleTestCase(TestCase): + + @use_pypi_server("test_case_name") + def test_something(self, server): + ... diff --git a/Doc/library/packaging.util.rst b/Doc/library/packaging.util.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.util.rst @@ -0,0 +1,186 @@ +:mod:`packaging.util` --- Miscellaneous utility functions +========================================================= + +.. module:: packaging.util + :synopsis: Miscellaneous utility functions. + + +This module contains various helpers for the other modules. + +.. XXX a number of functions are missing, but the module may be split first + (it's ginormous right now, some things could go to compat for example) + +.. function:: get_platform() + + Return a string that identifies the current platform. This is used mainly to + distinguish platform-specific build directories and platform-specific built + distributions. Typically includes the OS name and version and the + architecture (as supplied by 'os.uname()'), although the exact information + included depends on the OS; e.g. for IRIX the architecture isn't particularly + important (IRIX only runs on SGI hardware), but for Linux the kernel version + isn't particularly important. + + Examples of returned values: + + * ``linux-i586`` + * ``linux-alpha`` + * ``solaris-2.6-sun4u`` + * ``irix-5.3`` + * ``irix64-6.2`` + + For non-POSIX platforms, currently just returns ``sys.platform``. + + For Mac OS X systems the OS version reflects the minimal version on which + binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` + during the build of Python), not the OS version of the current system. + + For universal binary builds on Mac OS X the architecture value reflects + the univeral binary status instead of the architecture of the current + processor. For 32-bit universal binaries the architecture is ``fat``, + for 64-bit universal binaries the architecture is ``fat64``, and + for 4-way universal binaries the architecture is ``universal``. Starting + from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for + a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for + a univeral build with the i386 and x86_64 architectures + + Examples of returned values on Mac OS X: + + * ``macosx-10.3-ppc`` + + * ``macosx-10.3-fat`` + + * ``macosx-10.5-universal`` + + * ``macosx-10.6-intel`` + + .. XXX reinvention of platform module? + + +.. function:: convert_path(pathname) + + Return 'pathname' as a name that will work on the native filesystem, i.e. + split it on '/' and put it back together again using the current directory + separator. Needed because filenames in the setup script are always supplied + in Unix style, and have to be converted to the local convention before we + can actually use them in the filesystem. Raises :exc:`ValueError` on + non-Unix-ish systems if *pathname* either starts or ends with a slash. + + +.. function:: change_root(new_root, pathname) + + Return *pathname* with *new_root* prepended. If *pathname* is relative, this + is equivalent to ``os.path.join(new_root,pathname)`` Otherwise, it requires + making *pathname* relative and then joining the two, which is tricky on + DOS/Windows. + + +.. function:: check_environ() + + Ensure that 'os.environ' has all the environment variables we guarantee that + users can use in config files, command-line options, etc. Currently this + includes: + + * :envvar:`HOME` - user's home directory (Unix only) + * :envvar:`PLAT` - description of the current platform, including hardware + and OS (see :func:`get_platform`) + + +.. function:: find_executable(executable, path=None) + + Search the path for a given executable name. + + +.. function:: subst_vars(s, local_vars) + + Perform shell/Perl-style variable substitution on *s*. Every occurrence of + ``$`` followed by a name is considered a variable, and variable is + substituted by the value found in the *local_vars* dictionary, or in + ``os.environ`` if it's not in *local_vars*. *os.environ* is first + checked/augmented to guarantee that it contains certain values: see + :func:`check_environ`. Raise :exc:`ValueError` for any variables not found + in either *local_vars* or ``os.environ``. + + Note that this is not a fully-fledged string interpolation function. A valid + ``$variable`` can consist only of upper and lower case letters, numbers and + an underscore. No { } or ( ) style quoting is available. + + +.. function:: split_quoted(s) + + Split a string up according to Unix shell-like rules for quotes and + backslashes. In short: words are delimited by spaces, as long as those spaces + are not escaped by a backslash, or inside a quoted string. Single and double + quotes are equivalent, and the quote characters can be backslash-escaped. + The backslash is stripped from any two-character escape sequence, leaving + only the escaped character. The quote characters are stripped from any + quoted string. Returns a list of words. + + .. TODO Should probably be moved into the standard library. + + +.. function:: execute(func, args[, msg=None, verbose=0, dry_run=0]) + + Perform some action that affects the outside world (for instance, writing to + the filesystem). Such actions are special because they are disabled by the + *dry_run* flag. This method takes care of all that bureaucracy for you; + all you have to do is supply the function to call and an argument tuple for + it (to embody the "external action" being performed), and an optional message + to print. + + +.. function:: newer(source, target) + + Return true if *source* exists and is more recently modified than *target*, + or if *source* exists and *target* doesn't. Return false if both exist and + *target* is the same age or newer than *source*. Raise + :exc:`PackagingFileError` if *source* does not exist. + + +.. function:: strtobool(val) + + Convert a string representation of truth to true (1) or false (0). + + True values are ``y``, ``yes``, ``t``, ``true``, ``on`` and ``1``; false + values are ``n``, ``no``, ``f``, ``false``, ``off`` and ``0``. Raises + :exc:`ValueError` if *val* is anything else. + +.. TODO Add :term: markup to bytecode when merging into the stdlib + +.. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None]) + + Byte-compile a collection of Python source files to either :file:`.pyc` or + :file:`.pyo` files in the same directory. *py_files* is a list of files to + compile; any files that don't end in :file:`.py` are silently skipped. + *optimize* must be one of the following: + + * ``0`` - don't optimize (generate :file:`.pyc`) + * ``1`` - normal optimization (like ``python -O``) + * ``2`` - extra optimization (like ``python -OO``) + + If *force* is true, all files are recompiled regardless of timestamps. + + The source filename encoded in each bytecode file defaults to the filenames + listed in *py_files*; you can modify these with *prefix* and *basedir*. + *prefix* is a string that will be stripped off of each source filename, and + *base_dir* is a directory name that will be prepended (after *prefix* is + stripped). You can supply either or both (or neither) of *prefix* and + *base_dir*, as you wish. + + If *dry_run* is true, doesn't actually do anything that would affect the + filesystem. + + Byte-compilation is either done directly in this interpreter process with the + standard :mod:`py_compile` module, or indirectly by writing a temporary + script and executing it. Normally, you should let :func:`byte_compile` + figure out to use direct compilation or not (see the source for details). + The *direct* flag is used by the script generated in indirect mode; unless + you know what you're doing, leave it set to ``None``. + + +.. function:: rfc822_escape(header) + + Return a version of *header* escaped for inclusion in an :rfc:`822` header, by + ensuring there are 8 spaces space after each newline. Note that it does no + other modification of the string. + + .. TODO this _can_ be replaced diff --git a/Doc/library/packaging.version.rst b/Doc/library/packaging.version.rst new file mode 100644 --- /dev/null +++ b/Doc/library/packaging.version.rst @@ -0,0 +1,104 @@ +:mod:`packaging.version` --- Version number classes +=================================================== + +.. module:: packaging.version + :synopsis: Classes that represent project version numbers. + + +This module contains classes and functions useful to deal with version numbers. +It's an implementation of version specifiers `as defined in PEP 345 +`_. + + +Version numbers +--------------- + +.. class:: NormalizedVersion(self, s, error_on_huge_major_num=True) + + A specific version of a distribution, as described in PEP 345. *s* is a + string object containing the version number (for example ``'1.2b1'``), + *error_on_huge_major_num* a boolean specifying whether to consider an + apparent use of a year or full date as the major version number an error. + + The rationale for the second argument is that there were projects using years + or full dates as version numbers, which could cause problems with some + packaging systems sorting. + + Instances of this class can be compared and sorted:: + + >>> NormalizedVersion('1.2b1') < NormalizedVersion('1.2') + True + + :class:`NormalizedVersion` is used internally by :class:`VersionPredicate` to + do its work. + + +.. class:: IrrationalVersionError + + Exception raised when an invalid string is given to + :class:`NormalizedVersion`. + + >>> NormalizedVersion("irrational_version_number") + ... + IrrationalVersionError: irrational_version_number + + +.. function:: suggest_normalized_version(s) + + Before standardization in PEP 386, various schemes were in use. Packaging + provides a function to try to convert any string to a valid, normalized + version:: + + >>> suggest_normalized_version('2.1-rc1') + 2.1c1 + + + If :func:`suggest_normalized_version` can't make sense of the given string, + it will return ``None``:: + + >>> print(suggest_normalized_version('not a version')) + None + + +Version predicates +------------------ + +.. class:: VersionPredicate(predicate) + + This class deals with the parsing of field values like + ``ProjectName (>=version)``. + + .. method:: match(version) + + Test if a version number matches the predicate: + + >>> version = VersionPredicate("ProjectName (<1.2, >1.0)") + >>> version.match("1.2.1") + False + >>> version.match("1.1.1") + True + + +Validation helpers +------------------ + +If you want to use :term:`LBYL`-style checks instead of instantiating the +classes and catching :class:`IrrationalVersionError` and :class:`ValueError`, +you can use these functions: + +.. function:: is_valid_version(predicate) + + Check whether the given string is a valid version number. Example of valid + strings: ``'1.2'``, ``'4.2.0.dev4'``, ``'2.5.4.post2'``. + + +.. function:: is_valid_versions(predicate) + + Check whether the given string is a valid value for specifying multiple + versions, such as in the Requires-Python field. Example: ``'2.7, >=3.2'``. + + +.. function:: is_valid_predicate(predicate) + + Check whether the given string is a valid version predicate. Examples: + ``'some.project == 4.5, <= 4.7'``, ``'speciallib (> 1.0, != 1.4.2, < 2.0)'``. diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -193,7 +193,7 @@ ------- To demonstrate several uses of the :func:`pprint` function and its parameters, -let's fetch information about a package from PyPI:: +let's fetch information about a project from PyPI:: >>> import json >>> import pprint @@ -201,8 +201,8 @@ >>> with urlopen('http://pypi.python.org/pypi/configparser/json') as url: ... http_info = url.info() ... raw_data = url.read().decode(http_info.get_content_charset()) - >>> package_data = json.loads(raw_data) - >>> result = {'headers': http_info.items(), 'body': package_data} + >>> project_info = json.loads(raw_data) + >>> result = {'headers': http_info.items(), 'body': project_info} In its basic form, :func:`pprint` shows the whole object:: diff --git a/Doc/library/python.rst b/Doc/library/python.rst --- a/Doc/library/python.rst +++ b/Doc/library/python.rst @@ -25,4 +25,5 @@ inspect.rst site.rst fpectl.rst + packaging.rst distutils.rst diff --git a/Doc/library/random.rst b/Doc/library/random.rst --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -43,6 +43,12 @@ uses the system function :func:`os.urandom` to generate random numbers from sources provided by the operating system. +.. warning:: + + The generators of the :mod:`random` module should not be used for security + purposes. Use :func:`ssl.RAND_bytes` if you require a cryptographically + secure pseudorandom number generator. + Bookkeeping functions: diff --git a/Doc/library/re.rst b/Doc/library/re.rst --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -1301,24 +1301,27 @@ to combine those into a single master regular expression and to loop over successive matches:: - Token = collections.namedtuple('Token', 'typ value line column') + import collections + import re + + Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column']) def tokenize(s): - keywords = {'IF', 'THEN', 'FOR', 'NEXT', 'GOSUB', 'RETURN'} - tok_spec = [ - ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number - ('ASSIGN', r':='), # Assignment operator - ('END', ';'), # Statement terminator - ('ID', r'[A-Za-z]+'), # Identifiers - ('OP', r'[+*\/\-]'), # Arithmetic operators - ('NEWLINE', r'\n'), # Line endings - ('SKIP', r'[ \t]'), # Skip over spaces and tabs + keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'} + token_specification = [ + ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number + ('ASSIGN', r':='), # Assignment operator + ('END', r';'), # Statement terminator + ('ID', r'[A-Za-z]+'), # Identifiers + ('OP', r'[+*\/\-]'), # Arithmetic operators + ('NEWLINE', r'\n'), # Line endings + ('SKIP', r'[ \t]'), # Skip over spaces and tabs ] - tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec) - gettok = re.compile(tok_re).match + tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification) + get_token = re.compile(tok_regex).match line = 1 pos = line_start = 0 - mo = gettok(s) + mo = get_token(s) while mo is not None: typ = mo.lastgroup if typ == 'NEWLINE': @@ -1330,13 +1333,15 @@ typ = val yield Token(typ, val, line, mo.start()-line_start) pos = mo.end() - mo = gettok(s, pos) + mo = get_token(s, pos) if pos != len(s): raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line)) - statements = '''\ - total := total + price * quantity; - tax := price * 0.05; + statements = ''' + IF quantity THEN + total := total + price * quantity; + tax := price * 0.05; + ENDIF; ''' for token in tokenize(statements): @@ -1344,17 +1349,22 @@ The tokenizer produces the following output:: - Token(typ='ID', value='total', line=1, column=8) - Token(typ='ASSIGN', value=':=', line=1, column=14) - Token(typ='ID', value='total', line=1, column=17) - Token(typ='OP', value='+', line=1, column=23) - Token(typ='ID', value='price', line=1, column=25) - Token(typ='OP', value='*', line=1, column=31) - Token(typ='ID', value='quantity', line=1, column=33) - Token(typ='END', value=';', line=1, column=41) - Token(typ='ID', value='tax', line=2, column=9) - Token(typ='ASSIGN', value=':=', line=2, column=13) - Token(typ='ID', value='price', line=2, column=16) - Token(typ='OP', value='*', line=2, column=22) - Token(typ='NUMBER', value='0.05', line=2, column=24) - Token(typ='END', value=';', line=2, column=28) + Token(typ='IF', value='IF', line=2, column=5) + Token(typ='ID', value='quantity', line=2, column=8) + Token(typ='THEN', value='THEN', line=2, column=17) + Token(typ='ID', value='total', line=3, column=9) + Token(typ='ASSIGN', value=':=', line=3, column=15) + Token(typ='ID', value='total', line=3, column=18) + Token(typ='OP', value='+', line=3, column=24) + Token(typ='ID', value='price', line=3, column=26) + Token(typ='OP', value='*', line=3, column=32) + Token(typ='ID', value='quantity', line=3, column=34) + Token(typ='END', value=';', line=3, column=42) + Token(typ='ID', value='tax', line=4, column=9) + Token(typ='ASSIGN', value=':=', line=4, column=13) + Token(typ='ID', value='price', line=4, column=16) + Token(typ='OP', value='*', line=4, column=22) + Token(typ='NUMBER', value='0.05', line=4, column=24) + Token(typ='END', value=';', line=4, column=28) + Token(typ='ENDIF', value='ENDIF', line=5, column=5) + Token(typ='END', value=';', line=5, column=10) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -187,10 +187,9 @@ Send the signal *signum* to the thread *thread_id*, another thread in the same process as the caller. The signal is asynchronously directed to thread. - *thread_id* can be read from the :attr:`~threading.Thread.ident` attribute - of :attr:`threading.Thread`. For example, - ``threading.current_thread().ident`` gives the identifier of the current - thread. + Use :func:`threading.get_ident()` or the :attr:`~threading.Thread.ident` + attribute of :attr:`threading.Thread` to get a 'thread identifier' for + *thread_id*. If *signum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if a thread is still running. diff --git a/Doc/library/site.rst b/Doc/library/site.rst --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -129,6 +129,10 @@ unless the :program:`python` interpreter was started with the :option:`-S` flag. + .. versionchanged:: 3.3 + This function used to be called unconditionnally. + + .. function:: addsitedir(sitedir, known_paths=None) Adds a directory to sys.path and processes its pth files. diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -153,8 +153,21 @@ .. method:: BaseServer.serve_forever(poll_interval=0.5) Handle requests until an explicit :meth:`shutdown` request. Polls for - shutdown every *poll_interval* seconds. + shutdown every *poll_interval* seconds. It also calls + :meth:`service_actions` which may be used by a subclass or Mixin to provide + various cleanup actions. For e.g. ForkingMixin class uses + :meth:`service_actions` to cleanup the zombie child processes. + .. versionchanged:: 3.3 + Added service_actions call to the serve_forever method. + + +.. method:: BaseServer.service_actions() + + This is called by the serve_forever loop. This method is can be overridden + by Mixin's to add cleanup or service specific actions. + + .. versionadded:: 3.3 .. method:: BaseServer.shutdown() diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -162,6 +162,35 @@ Random generation ^^^^^^^^^^^^^^^^^ +.. function:: RAND_bytes(num) + + Returns *num* cryptographically strong pseudo-random bytes. Raises an + :class:`SSLError` if the PRNG has not been seeded with enough data or if the + operation is not supported by the current RAND method. :func:`RAND_status` + can be used to check the status of the PRNG and :func:`RAND_add` can be used + to seed the PRNG. + + Read the Wikipedia article, `Cryptographically secure pseudorandom number + generator (CSPRNG) + `_, + to get the requirements of a cryptographically generator. + + .. versionadded:: 3.3 + +.. function:: RAND_pseudo_bytes(num) + + Returns (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, + is_cryptographic is True if the bytes generated are cryptographically + strong. Raises an :class:`SSLError` if the operation is not supported by the + current RAND method. + + Generated pseudo-random byte sequences will be unique if they are of + sufficient length, but are not necessarily unpredictable. They can be used + for non-cryptographic purposes and for certain purposes in cryptographic + protocols, but usually not for key generation etc. + + .. versionadded:: 3.3 + .. function:: RAND_status() Returns True if the SSL pseudo-random number generator has been seeded with @@ -171,7 +200,7 @@ .. function:: RAND_egd(path) - If you are running an entropy-gathering daemon (EGD) somewhere, and ``path`` + If you are running an entropy-gathering daemon (EGD) somewhere, and *path* is the pathname of a socket connection open to it, this will read 256 bytes of randomness from the socket, and add it to the SSL pseudo-random number generator to increase the security of generated secret keys. This is @@ -182,8 +211,8 @@ .. function:: RAND_add(bytes, entropy) - Mixes the given ``bytes`` into the SSL pseudo-random number generator. The - parameter ``entropy`` (a float) is a lower bound on the entropy contained in + Mixes the given *bytes* into the SSL pseudo-random number generator. The + parameter *entropy* (a float) is a lower bound on the entropy contained in string (so you can always use :const:`0.0`). See :rfc:`1750` for more information on sources of entropy. diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -48,6 +48,17 @@ returned. +.. function:: get_ident() + + Return the 'thread identifier' of the current thread. This is a nonzero + integer. Its value has no direct meaning; it is intended as a magic cookie + to be used e.g. to index a dictionary of thread-specific data. Thread + identifiers may be recycled when a thread exits and another thread is + created. + + .. versionadded:: 3.3 + + .. function:: enumerate() Return a list of all :class:`Thread` objects currently alive. The list @@ -332,10 +343,10 @@ .. attribute:: ident The 'thread identifier' of this thread or ``None`` if the thread has not - been started. This is a nonzero integer. See the - :func:`thread.get_ident()` function. Thread identifiers may be recycled - when a thread exits and another thread is created. The identifier is - available even after the thread has exited. + been started. This is a nonzero integer. See the :func:`get_ident()` + function. Thread identifiers may be recycled when a thread exits and + another thread is created. The identifier is available even after the + thread has exited. .. method:: is_alive() diff --git a/Doc/packaging/builtdist.rst b/Doc/packaging/builtdist.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/builtdist.rst @@ -0,0 +1,307 @@ +.. _packaging-built-dist: + +**************************** +Creating Built Distributions +**************************** + +A "built distribution" is what you're probably used to thinking of either as a +"binary package" or an "installer" (depending on your background). It's not +necessarily binary, though, because it might contain only Python source code +and/or byte-code; and we don't call it a package, because that word is already +spoken for in Python. (And "installer" is a term specific to the world of +mainstream desktop systems.) + +A built distribution is how you make life as easy as possible for installers of +your module distribution: for users of RPM-based Linux systems, it's a binary +RPM; for Windows users, it's an executable installer; for Debian-based Linux +users, it's a Debian package; and so forth. Obviously, no one person will be +able to create built distributions for every platform under the sun, so the +Distutils are designed to enable module developers to concentrate on their +specialty---writing code and creating source distributions---while an +intermediary species called *packagers* springs up to turn source distributions +into built distributions for as many platforms as there are packagers. + +Of course, the module developer could be his own packager; or the packager could +be a volunteer "out there" somewhere who has access to a platform which the +original developer does not; or it could be software periodically grabbing new +source distributions and turning them into built distributions for as many +platforms as the software has access to. Regardless of who they are, a packager +uses the setup script and the :command:`bdist` command family to generate built +distributions. + +As a simple example, if I run the following command in the Distutils source +tree:: + + python setup.py bdist + +then the Distutils builds my module distribution (the Distutils itself in this +case), does a "fake" installation (also in the :file:`build` directory), and +creates the default type of built distribution for my platform. The default +format for built distributions is a "dumb" tar file on Unix, and a simple +executable installer on Windows. (That tar file is considered "dumb" because it +has to be unpacked in a specific location to work.) + +Thus, the above command on a Unix system creates +:file:`Distutils-1.0.{plat}.tar.gz`; unpacking this tarball from the right place +installs the Distutils just as though you had downloaded the source distribution +and run ``python setup.py install``. (The "right place" is either the root of +the filesystem or Python's :file:`{prefix}` directory, depending on the options +given to the :command:`bdist_dumb` command; the default is to make dumb +distributions relative to :file:`{prefix}`.) + +Obviously, for pure Python distributions, this isn't any simpler than just +running ``python setup.py install``\ ---but for non-pure distributions, which +include extensions that would need to be compiled, it can mean the difference +between someone being able to use your extensions or not. And creating "smart" +built distributions, such as an executable installer for +Windows, is far more convenient for users even if your distribution doesn't +include any extensions. + +The :command:`bdist` command has a :option:`--formats` option, similar to the +:command:`sdist` command, which you can use to select the types of built +distribution to generate: for example, :: + + python setup.py bdist --format=zip + +would, when run on a Unix system, create :file:`Distutils-1.0.{plat}.zip`\ +---again, this archive would be unpacked from the root directory to install the +Distutils. + +The available formats for built distributions are: + ++-------------+------------------------------+---------+ +| Format | Description | Notes | ++=============+==============================+=========+ +| ``gztar`` | gzipped tar file | (1),(3) | +| | (:file:`.tar.gz`) | | ++-------------+------------------------------+---------+ +| ``ztar`` | compressed tar file | \(3) | +| | (:file:`.tar.Z`) | | ++-------------+------------------------------+---------+ +| ``tar`` | tar file (:file:`.tar`) | \(3) | ++-------------+------------------------------+---------+ +| ``zip`` | zip file (:file:`.zip`) | (2),(4) | ++-------------+------------------------------+---------+ +| ``wininst`` | self-extracting ZIP file for | \(4) | +| | Windows | | ++-------------+------------------------------+---------+ +| ``msi`` | Microsoft Installer. | | ++-------------+------------------------------+---------+ + + +Notes: + +(1) + default on Unix + +(2) + default on Windows + +(3) + requires external utilities: :program:`tar` and possibly one of :program:`gzip`, + :program:`bzip2`, or :program:`compress` + +(4) + requires either external :program:`zip` utility or :mod:`zipfile` module (part + of the standard Python library since Python 1.6) + +You don't have to use the :command:`bdist` command with the :option:`--formats` +option; you can also use the command that directly implements the format you're +interested in. Some of these :command:`bdist` "sub-commands" actually generate +several similar formats; for instance, the :command:`bdist_dumb` command +generates all the "dumb" archive formats (``tar``, ``ztar``, ``gztar``, and +``zip``). The :command:`bdist` sub-commands, and the formats generated by +each, are: + ++--------------------------+-----------------------+ +| Command | Formats | ++==========================+=======================+ +| :command:`bdist_dumb` | tar, ztar, gztar, zip | ++--------------------------+-----------------------+ +| :command:`bdist_wininst` | wininst | ++--------------------------+-----------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-----------------------+ + +The following sections give details on the individual :command:`bdist_\*` +commands. + + +.. _packaging-creating-dumb: + +Creating dumb built distributions +================================= + +.. XXX Need to document absolute vs. prefix-relative packages here, but first + I have to implement it! + + +.. _packaging-creating-wininst: + +Creating Windows Installers +=========================== + +Executable installers are the natural format for binary distributions on +Windows. They display a nice graphical user interface, display some information +about the module distribution to be installed taken from the metadata in the +setup script, let the user select a few options, and start or cancel the +installation. + +Since the metadata is taken from the setup script, creating Windows installers +is usually as easy as running:: + + python setup.py bdist_wininst + +or the :command:`bdist` command with the :option:`--formats` option:: + + python setup.py bdist --formats=wininst + +If you have a pure module distribution (only containing pure Python modules and +packages), the resulting installer will be version independent and have a name +like :file:`foo-1.0.win32.exe`. These installers can even be created on Unix +platforms or Mac OS X. + +If you have a non-pure distribution, the extensions can only be created on a +Windows platform, and will be Python version dependent. The installer filename +will reflect this and now has the form :file:`foo-1.0.win32-py2.0.exe`. You +have to create a separate installer for every Python version you want to +support. + +.. TODO Add :term: markup to bytecode when merging into the stdlib + +The installer will try to compile pure modules into bytecode after installation +on the target system in normal and optimizing mode. If you don't want this to +happen for some reason, you can run the :command:`bdist_wininst` command with +the :option:`--no-target-compile` and/or the :option:`--no-target-optimize` +option. + +By default the installer will display the cool "Python Powered" logo when it is +run, but you can also supply your own 152x261 bitmap which must be a Windows +:file:`.bmp` file with the :option:`--bitmap` option. + +The installer will also display a large title on the desktop background window +when it is run, which is constructed from the name of your distribution and the +version number. This can be changed to another text by using the +:option:`--title` option. + +The installer file will be written to the "distribution directory" --- normally +:file:`dist/`, but customizable with the :option:`--dist-dir` option. + +.. _packaging-cross-compile-windows: + +Cross-compiling on Windows +========================== + +Starting with Python 2.6, packaging is capable of cross-compiling between +Windows platforms. In practice, this means that with the correct tools +installed, you can use a 32bit version of Windows to create 64bit extensions +and vice-versa. + +To build for an alternate platform, specify the :option:`--plat-name` option +to the build command. Valid values are currently 'win32', 'win-amd64' and +'win-ia64'. For example, on a 32bit version of Windows, you could execute:: + + python setup.py build --plat-name=win-amd64 + +to build a 64bit version of your extension. The Windows Installers also +support this option, so the command:: + + python setup.py build --plat-name=win-amd64 bdist_wininst + +would create a 64bit installation executable on your 32bit version of Windows. + +To cross-compile, you must download the Python source code and cross-compile +Python itself for the platform you are targetting - it is not possible from a +binary installtion of Python (as the .lib etc file for other platforms are +not included.) In practice, this means the user of a 32 bit operating +system will need to use Visual Studio 2008 to open the +:file:`PCBuild/PCbuild.sln` solution in the Python source tree and build the +"x64" configuration of the 'pythoncore' project before cross-compiling +extensions is possible. + +Note that by default, Visual Studio 2008 does not install 64bit compilers or +tools. You may need to reexecute the Visual Studio setup process and select +these tools (using Control Panel->[Add/Remove] Programs is a convenient way to +check or modify your existing install.) + +.. _packaging-postinstallation-script: + +The Postinstallation script +--------------------------- + +Starting with Python 2.3, a postinstallation script can be specified with the +:option:`--install-script` option. The basename of the script must be +specified, and the script filename must also be listed in the scripts argument +to the setup function. + +This script will be run at installation time on the target system after all the +files have been copied, with ``argv[1]`` set to :option:`-install`, and again at +uninstallation time before the files are removed with ``argv[1]`` set to +:option:`-remove`. + +The installation script runs embedded in the windows installer, every output +(``sys.stdout``, ``sys.stderr``) is redirected into a buffer and will be +displayed in the GUI after the script has finished. + +Some functions especially useful in this context are available as additional +built-in functions in the installation script. + +.. currentmodule:: bdist_wininst-postinst-script + +.. function:: directory_created(path) + file_created(path) + + These functions should be called when a directory or file is created by the + postinstall script at installation time. It will register *path* with the + uninstaller, so that it will be removed when the distribution is uninstalled. + To be safe, directories are only removed if they are empty. + + +.. function:: get_special_folder_path(csidl_string) + + This function can be used to retrieve special folder locations on Windows like + the Start Menu or the Desktop. It returns the full path to the folder. + *csidl_string* must be one of the following strings:: + + "CSIDL_APPDATA" + + "CSIDL_COMMON_STARTMENU" + "CSIDL_STARTMENU" + + "CSIDL_COMMON_DESKTOPDIRECTORY" + "CSIDL_DESKTOPDIRECTORY" + + "CSIDL_COMMON_STARTUP" + "CSIDL_STARTUP" + + "CSIDL_COMMON_PROGRAMS" + "CSIDL_PROGRAMS" + + "CSIDL_FONTS" + + If the folder cannot be retrieved, :exc:`OSError` is raised. + + Which folders are available depends on the exact Windows version, and probably + also the configuration. For details refer to Microsoft's documentation of the + c:function:`SHGetSpecialFolderPath` function. + + +.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]]) + + This function creates a shortcut. *target* is the path to the program to be + started by the shortcut. *description* is the description of the shortcut. + *filename* is the title of the shortcut that the user will see. *arguments* + specifies the command-line arguments, if any. *workdir* is the working directory + for the program. *iconpath* is the file containing the icon for the shortcut, + and *iconindex* is the index of the icon in the file *iconpath*. Again, for + details consult the Microsoft documentation for the :class:`IShellLink` + interface. + + +Vista User Access Control (UAC) +=============================== + +Starting with Python 2.6, bdist_wininst supports a :option:`--user-access-control` +option. The default is 'none' (meaning no UAC handling is done), and other +valid values are 'auto' (meaning prompt for UAC elevation if Python was +installed for all users) and 'force' (meaning always prompt for elevation). diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/commandhooks.rst @@ -0,0 +1,31 @@ +============= +Command hooks +============= + +Packaging provides a way of extending its commands by the use of pre- and +post- command hooks. The hooks are simple Python functions (or any callable +objects) and are specified in the config file using their full qualified names. +The pre-hooks are run after the command is finalized (its options are +processed), but before it is run. The post-hooks are run after the command +itself. Both types of hooks receive an instance of the command object. + +Sample usage of hooks +===================== + +Firstly, you need to make sure your hook is present in the path. This is usually +done by dropping them to the same folder where `setup.py` file lives :: + + # file: myhooks.py + def my_install_hook(install_cmd): + print "Oh la la! Someone is installing my project!" + +Then, you need to point to it in your `setup.cfg` file, under the appropriate +command section :: + + [install_dist] + pre-hook.project = myhooks.my_install_hook + +The hooks defined in different config files (system-wide, user-wide and +package-wide) do not override each other as long as they are specified with +different aliases (additional names after the dot). The alias in the example +above is ``project``. diff --git a/Doc/packaging/commandref.rst b/Doc/packaging/commandref.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/commandref.rst @@ -0,0 +1,349 @@ +.. _packaging-command-reference: + +***************** +Command Reference +***************** + +This reference briefly documents all standard Packaging commands and some of +their options. + +.. FIXME does not work: Use pysetup run --help-commands to list all + standard and extra commands availavble on your system, with their + description. Use pysetup run --help to get help about the options + of one command. + + +Preparing distributions +======================= + +:command:`check` +---------------- + +Perform some tests on the metadata of a distribution. + +For example, it verifies that all required metadata fields are provided in the +:file:`setup.cfg` file. + +.. TODO document reST checks + + +:command:`test` +--------------- + +Run a test suite. + +When doing test-driven development, or running automated builds that need +testing before they are installed for downloading or use, it's often useful to +be able to run a project's unit tests without actually installing the project +anywhere. The :command:`test` command runs project's unit tests without +actually installing it, by temporarily putting the project's source on +:data:`sys.path`, after first running :command:`build_ext -i` to ensure that any +C extensions are built. + +You can use this command in one of two ways: either by specifying a +unittest-compatible test suite for your project (or any callable that returns +it) or by passing a test runner function that will run your tests and display +results in the console. Both options take a Python dotted name in the form +``package.module.callable`` to specify the object to use. + +If none of these options are specified, Packaging will try to perform test +discovery using either unittest (for Python 3.2 and higher) or unittest2 (for +older versions, if installed). + +.. this is a pseudo-command name used to disambiguate the options in indexes and + links +.. program:: packaging test + +.. cmdoption:: --suite=NAME, -s NAME + + Specify the test suite (or module, class, or method) to be run. The default + for this option can be set by in the project's :file:`setup.cfg` file:: + + .. code-block:: cfg + + [test] + suite = mypackage.tests.get_all_tests + +.. cmdoption:: --runner=NAME, -r NAME + + Specify the test runner to be called. + + +:command:`config` +----------------- + +Perform distribution configuration. + + +The build step +============== + +This step is mainly useful to compile C/C++ libraries or extension modules. The +build commands can be run manually to check for syntax errors or packaging +issues (for example if the addition of a new source file was forgotten in the +:file:`setup.cfg` file), and is also run automatically by commands which need +it. Packaging checks the mtime of source and built files to avoid re-building +if it's not necessary. + + +:command:`build` +---------------- + +Build all files of a distribution, delegating to the other :command:`build_*` +commands to do the work. + + +:command:`build_clib` +--------------------- + +Build C libraries. + + +:command:`build_ext` +-------------------- + +Build C/C++ extension modules. + + +:command:`build_py` +------------------- + +Build the Python modules (just copy them to the build directory) and +byte-compile them to .pyc files. + + +:command:`build_scripts` +------------------------ +Build the scripts (just copy them to the build directory and adjust their +shebang if they're Python scripts). + + +:command:`clean` +---------------- + +Clean the build tree of the release. + +.. program:: packaging clean + +.. cmdoption:: --all, -a + + Remove build directories for modules, scripts, etc., not only temporary build + by-products. + + +Creating source and built distributions +======================================= + +:command:`sdist` +---------------- + +Build a source distribution for a release. + +It is recommended that you always build and upload a source distribution. Users +of OSes with easy access to compilers and users of advanced packaging tools will +prefer to compile from source rather than using pre-built distributions. For +Windows users, providing a binary installer is also recommended practice. + + +:command:`bdist` +---------------- + +Build a binary distribution for a release. + +This command will call other :command:`bdist_*` commands to create one or more +distributions depending on the options given. The default is to create a +.tar.gz archive on Unix and a zip archive on Windows or OS/2. + +.. program:: packaging bdist + +.. cmdoption:: --formats + + Binary formats to build (comma-separated list). + +.. cmdoption:: --show-formats + + Dump list of available formats. + + +:command:`bdist_dumb` +--------------------- + +Build a "dumb" installer, a simple archive of files that could be unpacked under +``$prefix`` or ``$exec_prefix``. + + +:command:`bdist_wininst` +------------------------ + +Build a Windows installer. + + +:command:`bdist_msi` +-------------------- + +Build a `Microsoft Installer`_ (.msi) file. + +.. _Microsoft Installer: http://msdn.microsoft.com/en-us/library/cc185688(VS.85).aspx + +In most cases, the :command:`bdist_msi` installer is a better choice than the +:command:`bdist_wininst` installer, because it provides better support for Win64 +platforms, allows administrators to perform non-interactive installations, and +allows installation through group policies. + + +Publishing distributions +======================== + +:command:`register` +------------------- + +This command registers the current release with the Python Package Index. This +is described in more detail in :PEP:`301`. + +.. TODO explain user and project registration with the web UI + + +:command:`upload` +----------------- + +Upload source and/or binary distributions to PyPI. + +The distributions have to be built on the same command line as the +:command:`upload` command; see :ref:`packaging-package-upload` for more info. + +.. program:: packaging upload + +.. cmdoption:: --sign, -s + + Sign each uploaded file using GPG (GNU Privacy Guard). The ``gpg`` program + must be available for execution on the system ``PATH``. + +.. cmdoption:: --identity=NAME, -i NAME + + Specify the identity or key name for GPG to use when signing. The value of + this option will be passed through the ``--local-user`` option of the + ``gpg`` program. + +.. cmdoption:: --show-response + + Display the full response text from server; this is useful for debugging + PyPI problems. + +.. cmdoption:: --repository=URL, -r URL + + The URL of the repository to upload to. Defaults to + http://pypi.python.org/pypi (i.e., the main PyPI installation). + +.. cmdoption:: --upload-docs + + Also run :command:`upload_docs`. Mainly useful as a default value in + :file:`setup.cfg` (on the command line, it's shorter to just type both + commands). + + +:command:`upload_docs` +---------------------- + +Upload HTML documentation to PyPI. + +PyPI now supports publishing project documentation at a URI of the form +``http://packages.python.org/``. :command:`upload_docs` will create +the necessary zip file out of a documentation directory and will post to the +repository. + +Note that to upload the documentation of a project, the corresponding version +must already be registered with PyPI, using the :command:`register` command --- +just like with :command:`upload`. + +Assuming there is an ``Example`` project with documentation in the subdirectory +:file:`docs`, for example:: + + Example/ + example.py + setup.cfg + docs/ + build/ + html/ + index.html + tips_tricks.html + conf.py + index.txt + tips_tricks.txt + +You can simply specify the directory with the HTML files in your +:file:`setup.cfg` file: + +.. code-block:: cfg + + [upload_docs] + upload-dir = docs/build/html + + +.. program:: packaging upload_docs + +.. cmdoption:: --upload-dir + + The directory to be uploaded to the repository. By default documentation + is searched for in ``docs`` (or ``doc``) directory in project root. + +.. cmdoption:: --show-response + + Display the full response text from server; this is useful for debugging + PyPI problems. + +.. cmdoption:: --repository=URL, -r URL + + The URL of the repository to upload to. Defaults to + http://pypi.python.org/pypi (i.e., the main PyPI installation). + + +The install step +================ + +These commands are used by end-users of a project using :program:`pysetup` or +another compatible installer. Each command will run the corresponding +:command:`build_*` command and then move the built files to their destination on +the target system. + + +:command:`install_dist` +----------------------- + +Install a distribution, delegating to the other :command:`install_*` commands to +do the work. + +.. program:: packaging install_dist + +.. cmdoption:: --user + + Install in user site-packages directory (see :PEP:`370`). + + +:command:`install_data` +----------------------- + +Install data files. + + +:command:`install_distinfo` +--------------------------- + +Install files recording details of the installation as specified in :PEP:`376`. + + +:command:`install_headers` +-------------------------- + +Install C/C++ header files. + + +:command:`install_lib` +---------------------- + +Install C library files. + + +:command:`install_scripts` +-------------------------- + +Install scripts. diff --git a/Doc/packaging/configfile.rst b/Doc/packaging/configfile.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/configfile.rst @@ -0,0 +1,125 @@ +.. _packaging-setup-config: + +************************************ +Writing the Setup Configuration File +************************************ + +Often, it's not possible to write down everything needed to build a distribution +*a priori*: you may need to get some information from the user, or from the +user's system, in order to proceed. As long as that information is fairly +simple---a list of directories to search for C header files or libraries, for +example---then providing a configuration file, :file:`setup.cfg`, for users to +edit is a cheap and easy way to solicit it. Configuration files also let you +provide default values for any command option, which the installer can then +override either on the command line or by editing the config file. + +The setup configuration file is a useful middle-ground between the setup script +---which, ideally, would be opaque to installers [#]_---and the command line to +the setup script, which is outside of your control and entirely up to the +installer. In fact, :file:`setup.cfg` (and any other Distutils configuration +files present on the target system) are processed after the contents of the +setup script, but before the command line. This has several useful +consequences: + +.. If you have more advanced needs, such as determining which extensions to + build based on what capabilities are present on the target system, then you + need the Distutils auto-configuration facility. This started to appear in + Distutils 0.9 but, as of this writing, isn't mature or stable enough yet + for real-world use. + +* installers can override some of what you put in :file:`setup.py` by editing + :file:`setup.cfg` + +* you can provide non-standard defaults for options that are not easily set in + :file:`setup.py` + +* installers can override anything in :file:`setup.cfg` using the command-line + options to :file:`setup.py` + +The basic syntax of the configuration file is simple:: + + [command] + option = value + ... + +where *command* is one of the Distutils commands (e.g. :command:`build_py`, +:command:`install_dist`), and *option* is one of the options that command supports. +Any number of options can be supplied for each command, and any number of +command sections can be included in the file. Blank lines are ignored, as are +comments, which run from a ``'#'`` character until the end of the line. Long +option values can be split across multiple lines simply by indenting the +continuation lines. + +You can find out the list of options supported by a particular command with the +universal :option:`--help` option, e.g. :: + + > python setup.py --help build_ext + [...] + Options for 'build_ext' command: + --build-lib (-b) directory for compiled extension modules + --build-temp (-t) directory for temporary files (build by-products) + --inplace (-i) ignore build-lib and put compiled extensions into the + source directory alongside your pure Python modules + --include-dirs (-I) list of directories to search for header files + --define (-D) C preprocessor macros to define + --undef (-U) C preprocessor macros to undefine + --swig-opts list of SWIG command-line options + [...] + +.. XXX do we want to support ``setup.py --help metadata``? + +Note that an option spelled :option:`--foo-bar` on the command line is spelled +:option:`foo_bar` in configuration files. + +For example, say you want your extensions to be built "in-place"---that is, you +have an extension :mod:`pkg.ext`, and you want the compiled extension file +(:file:`ext.so` on Unix, say) to be put in the same source directory as your +pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the +:option:`--inplace` option on the command line to ensure this:: + + python setup.py build_ext --inplace + +But this requires that you always specify the :command:`build_ext` command +explicitly, and remember to provide :option:`--inplace`. An easier way is to +"set and forget" this option, by encoding it in :file:`setup.cfg`, the +configuration file for this distribution:: + + [build_ext] + inplace = 1 + +This will affect all builds of this module distribution, whether or not you +explicitly specify :command:`build_ext`. If you include :file:`setup.cfg` in +your source distribution, it will also affect end-user builds---which is +probably a bad idea for this option, since always building extensions in-place +would break installation of the module distribution. In certain peculiar cases, +though, modules are built right in their installation directory, so this is +conceivably a useful ability. (Distributing extensions that expect to be built +in their installation directory is almost always a bad idea, though.) + +Another example: certain commands take options that vary from project to +project but not depending on the installation system, for example, +:command:`test` needs to know where your test suite is located and what test +runner to use; likewise, :command:`upload_docs` can find HTML documentation in +a :file:`doc` or :file:`docs` directory, but needs an option to find files in +:file:`docs/build/html`. Instead of having to type out these options each +time you want to run the command, you can put them in the project's +:file:`setup.cfg`:: + + [test] + suite = packaging.tests + + [upload_docs] + upload-dir = docs/build/html + + +.. seealso:: + + :ref:`packaging-config-syntax` in "Installing Python Projects" + More information on the configuration files is available in the manual for + system administrators. + + +.. rubric:: Footnotes + +.. [#] This ideal probably won't be achieved until auto-configuration is fully + supported by the Distutils. diff --git a/Doc/packaging/examples.rst b/Doc/packaging/examples.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/examples.rst @@ -0,0 +1,334 @@ +.. _packaging-examples: + +******** +Examples +******** + +This chapter provides a number of basic examples to help get started with +Packaging. + + +.. _packaging-pure-mod: + +Pure Python distribution (by module) +==================================== + +If you're just distributing a couple of modules, especially if they don't live +in a particular package, you can specify them individually using the +:option:`py_modules` option in the setup script. + +In the simplest case, you'll have two files to worry about: a setup script and +the single module you're distributing, :file:`foo.py` in this example:: + + / + setup.py + foo.py + +(In all diagrams in this section, ** will refer to the distribution root +directory.) A minimal setup script to describe this situation would be:: + + from packaging.core import setup + setup(name='foo', + version='1.0', + py_modules=['foo']) + +Note that the name of the distribution is specified independently with the +:option:`name` option, and there's no rule that says it has to be the same as +the name of the sole module in the distribution (although that's probably a good +convention to follow). However, the distribution name is used to generate +filenames, so you should stick to letters, digits, underscores, and hyphens. + +Since :option:`py_modules` is a list, you can of course specify multiple +modules, e.g. if you're distributing modules :mod:`foo` and :mod:`bar`, your +setup might look like this:: + + / + setup.py + foo.py + bar.py + +and the setup script might be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + py_modules=['foo', 'bar']) + +You can put module source files into another directory, but if you have enough +modules to do that, it's probably easier to specify modules by package rather +than listing them individually. + + +.. _packaging-pure-pkg: + +Pure Python distribution (by package) +===================================== + +If you have more than a couple of modules to distribute, especially if they are +in multiple packages, it's probably easier to specify whole packages rather than +individual modules. This works even if your modules are not in a package; you +can just tell the Distutils to process modules from the root package, and that +works the same as any other package (except that you don't have to have an +:file:`__init__.py` file). + +The setup script from the last example could also be written as :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['']) + +(The empty string stands for the root package.) + +If those two files are moved into a subdirectory, but remain in the root +package, e.g.:: + + / + setup.py + src/ + foo.py + bar.py + +then you would still specify the root package, but you have to tell the +Distutils where source files in the root package live:: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'': 'src'}, + packages=['']) + +More typically, though, you will want to distribute multiple modules in the same +package (or in sub-packages). For example, if the :mod:`foo` and :mod:`bar` +modules belong in package :mod:`foobar`, one way to lay out your source tree is + +:: + + / + setup.py + foobar/ + __init__.py + foo.py + bar.py + +This is in fact the default layout expected by the Distutils, and the one that +requires the least work to describe in your setup script:: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['foobar']) + +If you want to put modules in directories not named for their package, then you +need to use the :option:`package_dir` option again. For example, if the +:file:`src` directory holds modules in the :mod:`foobar` package:: + + / + setup.py + src/ + __init__.py + foo.py + bar.py + +an appropriate setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'foobar': 'src'}, + packages=['foobar']) + +Or, you might put modules from your main package right in the distribution +root:: + + / + setup.py + __init__.py + foo.py + bar.py + +in which case your setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + package_dir={'foobar': ''}, + packages=['foobar']) + +(The empty string also stands for the current directory.) + +If you have sub-packages, they must be explicitly listed in :option:`packages`, +but any entries in :option:`package_dir` automatically extend to sub-packages. +(In other words, the Distutils does *not* scan your source tree, trying to +figure out which directories correspond to Python packages by looking for +:file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: + + / + setup.py + foobar/ + __init__.py + foo.py + bar.py + subfoo/ + __init__.py + blah.py + +then the corresponding setup script would be :: + + from packaging.core import setup + setup(name='foobar', + version='1.0', + packages=['foobar', 'foobar.subfoo']) + +(Again, the empty string in :option:`package_dir` stands for the current +directory.) + + +.. _packaging-single-ext: + +Single extension module +======================= + +Extension modules are specified using the :option:`ext_modules` option. +:option:`package_dir` has no effect on where extension source files are found; +it only affects the source for pure Python modules. The simplest case, a +single extension module in a single C source file, is:: + + / + setup.py + foo.c + +If the :mod:`foo` extension belongs in the root package, the setup script for +this could be :: + + from packaging.core import setup, Extension + setup(name='foobar', + version='1.0', + ext_modules=[Extension('foo', ['foo.c'])]) + +If the extension actually belongs in a package, say :mod:`foopkg`, then + +With exactly the same source tree layout, this extension can be put in the +:mod:`foopkg` package simply by changing the name of the extension:: + + from packaging.core import setup, Extension + setup(name='foobar', + version='1.0', + packages=['foopkg'], + ext_modules=[Extension('foopkg.foo', ['foo.c'])]) + + +Checking metadata +================= + +The ``check`` command allows you to verify if your project's metadata +meets the minimum requirements to build a distribution. + +To run it, just call it using your :file:`setup.py` script. If something is +missing, ``check`` will display a warning. + +Let's take an example with a simple script:: + + from packaging.core import setup + + setup(name='foobar') + +.. TODO configure logging StreamHandler to match this output + +Running the ``check`` command will display some warnings:: + + $ python setup.py check + running check + warning: check: missing required metadata: version, home_page + warning: check: missing metadata: either (author and author_email) or + (maintainer and maintainer_email) must be supplied + + +If you use the reStructuredText syntax in the ``long_description`` field and +`Docutils `_ is installed you can check if +the syntax is fine with the ``check`` command, using the ``restructuredtext`` +option. + +For example, if the :file:`setup.py` script is changed like this:: + + from packaging.core import setup + + desc = """\ + Welcome to foobar! + =============== + + This is the description of the ``foobar`` project. + """ + + setup(name='foobar', + version='1.0', + author=u'Tarek Ziad?', + author_email='tarek at ziade.org', + summary='Foobar utilities' + description=desc, + home_page='http://example.com') + +Where the long description is broken, ``check`` will be able to detect it +by using the :mod:`docutils` parser:: + + $ python setup.py check --restructuredtext + running check + warning: check: Title underline too short. (line 2) + warning: check: Could not finish the parsing. + + +.. _packaging-reading-metadata: + +Reading the metadata +==================== + +The :func:`packaging.core.setup` function provides a command-line interface +that allows you to query the metadata fields of a project through the +:file:`setup.py` script of a given project:: + + $ python setup.py --name + foobar + +This call reads the ``name`` metadata by running the +:func:`packaging.core.setup` function. When a source or binary +distribution is created with Distutils, the metadata fields are written +in a static file called :file:`PKG-INFO`. When a Distutils-based project is +installed in Python, the :file:`PKG-INFO` file is copied alongside the modules +and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, +where ``NAME`` is the name of the project, ``VERSION`` its version as defined +in the Metadata, and ``pyX.X`` the major and minor version of Python like +``2.7`` or ``3.2``. + +You can read back this static file, by using the +:class:`packaging.dist.Metadata` class and its +:func:`read_pkg_file` method:: + + >>> from packaging.metadata import Metadata + >>> metadata = Metadata() + >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) + >>> metadata.name + 'distribute' + >>> metadata.version + '0.6.8' + >>> metadata.description + 'Easily download, build, install, upgrade, and uninstall Python packages' + +Notice that the class can also be instantiated with a metadata file path to +loads its values:: + + >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' + >>> Metadata(pkg_info_path).name + 'distribute' + + +.. XXX These comments have been here for at least ten years. Write the + sections or delete the comments (we can maybe ask Greg Ward about + the planned contents). (Unindent to make them section titles) + + .. multiple-ext:: + + Multiple extension modules + ========================== + + Putting it all together + ======================= diff --git a/Doc/packaging/extending.rst b/Doc/packaging/extending.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/extending.rst @@ -0,0 +1,95 @@ +.. _extending-packaging: + +******************* +Extending Distutils +******************* + +Distutils can be extended in various ways. Most extensions take the form of new +commands or replacements for existing commands. New commands may be written to +support new types of platform-specific packaging, for example, while +replacements for existing commands may be made to modify details of how the +command operates on a package. + +Most extensions of the packaging are made within :file:`setup.py` scripts that +want to modify existing commands; many simply add a few file extensions that +should be copied into packages in addition to :file:`.py` files as a +convenience. + +Most packaging command implementations are subclasses of the +:class:`packaging.cmd.Command` class. New commands may directly inherit from +:class:`Command`, while replacements often derive from :class:`Command` +indirectly, directly subclassing the command they are replacing. Commands are +required to derive from :class:`Command`. + +.. .. _extend-existing: + Extending existing commands + =========================== + + +.. .. _new-commands: + Writing new commands + ==================== + + +Integrating new commands +======================== + +There are different ways to integrate new command implementations into +packaging. The most difficult is to lobby for the inclusion of the new features +in packaging itself, and wait for (and require) a version of Python that +provides that support. This is really hard for many reasons. + +The most common, and possibly the most reasonable for most needs, is to include +the new implementations with your :file:`setup.py` script, and cause the +:func:`packaging.core.setup` function use them:: + + from packaging.core import setup + from packaging.command.build_py import build_py as _build_py + + class build_py(_build_py): + """Specialized Python source builder.""" + + # implement whatever needs to be different... + + setup(..., cmdclass={'build_py': build_py}) + +This approach is most valuable if the new implementations must be used to use a +particular package, as everyone interested in the package will need to have the +new command implementation. + +Beginning with Python 2.4, a third option is available, intended to allow new +commands to be added which can support existing :file:`setup.py` scripts without +requiring modifications to the Python installation. This is expected to allow +third-party extensions to provide support for additional packaging systems, but +the commands can be used for anything packaging commands can be used for. A new +configuration option, :option:`command_packages` (command-line option +:option:`--command-packages`), can be used to specify additional packages to be +searched for modules implementing commands. Like all packaging options, this +can be specified on the command line or in a configuration file. This option +can only be set in the ``[global]`` section of a configuration file, or before +any commands on the command line. If set in a configuration file, it can be +overridden from the command line; setting it to an empty string on the command +line causes the default to be used. This should never be set in a configuration +file provided with a package. + +This new option can be used to add any number of packages to the list of +packages searched for command implementations; multiple package names should be +separated by commas. When not specified, the search is only performed in the +:mod:`packaging.command` package. When :file:`setup.py` is run with the option +:option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages +:mod:`packaging.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched +in that order. New commands are expected to be implemented in modules of the +same name as the command by classes sharing the same name. Given the example +command-line option above, the command :command:`bdist_openpkg` could be +implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or +:class:`buildcmds.bdist_openpkg.bdist_openpkg`. + + +Adding new distribution types +============================= + +Commands that create distributions (files in the :file:`dist/` directory) need +to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that +:command:`upload` can upload it to PyPI. The *filename* in the pair contains no +path information, only the name of the file itself. In dry-run mode, pairs +should still be added to represent what would have been created. diff --git a/Doc/packaging/index.rst b/Doc/packaging/index.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/index.rst @@ -0,0 +1,45 @@ +.. _packaging-index: + +############################## + Distributing Python Projects +############################## + +:Authors: The Fellowship of the Packaging +:Email: distutils-sig at python.org +:Release: |version| +:Date: |today| + +This document describes Packaging for Python authors, describing how to use the +module to make Python applications, packages or modules easily available to a +wider audience with very little overhead for build/release/install mechanics. + +.. toctree:: + :maxdepth: 2 + :numbered: + + tutorial + setupcfg + introduction + setupscript + configfile + sourcedist + builtdist + packageindex + uploading + examples + extending + commandhooks + commandref + + +.. seealso:: + + :ref:`packaging-install-index` + A user-centered manual which includes information on adding projects + into an existing Python installation. You do not need to be a Python + programmer to read this manual. + + :mod:`packaging` + A library reference for developers of packaging tools wanting to use + standalone building blocks like :mod:`~packaging.version` or + :mod:`~packaging.metadata`, or extend Packaging itself. diff --git a/Doc/packaging/introduction.rst b/Doc/packaging/introduction.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/introduction.rst @@ -0,0 +1,193 @@ +.. _packaging-intro: + +***************************** +An Introduction to Packaging +***************************** + +This document covers using Packaging to distribute your Python modules, +concentrating on the role of developer/distributor. If you're looking for +information on installing Python modules you should refer to the +:ref:`packaging-install-index` chapter. + +Throughout this documentation, the terms "Distutils", "the Distutils" and +"Packaging" will be used interchangeably. + +.. _packaging-concepts: + +Concepts & Terminology +====================== + +Using Distutils is quite simple both for module developers and for +users/administrators installing third-party modules. As a developer, your +responsibilities (apart from writing solid, well-documented and well-tested +code, of course!) are: + +* writing a setup script (:file:`setup.py` by convention) + +* (optional) writing a setup configuration file + +* creating a source distribution + +* (optional) creating one or more "built" (binary) distributions of your + project + +All of these tasks are covered in this document. + +Not all module developers have access to multiple platforms, so one cannot +expect them to create buildt distributions for every platform. To remedy +this, it is hoped that intermediaries called *packagers* will arise to address +this need. Packagers take source distributions released by module developers, +build them on one or more platforms and release the resulting built +distributions. Thus, users on a greater range of platforms will be able to +install the most popular Python modules in the most natural way for their +platform without having to run a setup script or compile a single line of code. + + +.. _packaging-simple-example: + +A Simple Example +================ + +A setup script is usually quite simple, although since it's written in Python +there are no arbitrary limits to what you can do with it, though you should be +careful about putting expensive operations in your setup script. +Unlike, say, Autoconf-style configure scripts the setup script may be run +multiple times in the course of building and installing a module +distribution. + +If all you want to do is distribute a module called :mod:`foo`, contained in a +file :file:`foo.py`, then your setup script can be as simple as:: + + from packaging.core import setup + setup(name='foo', + version='1.0', + py_modules=['foo']) + +Some observations: + +* most information that you supply to the Distutils is supplied as keyword + arguments to the :func:`setup` function + +* those keyword arguments fall into two categories: package metadata (name, + version number, etc.) and information about what's in the package (a list + of pure Python modules in this case) + +* modules are specified by module name, not filename (the same will hold true + for packages and extensions) + +* it's recommended that you supply a little more metadata than we have in the + example. In particular your name, email address and a URL for the + project if appropriate (see section :ref:`packaging-setup-script` for an example) + +To create a source distribution for this module you would create a setup +script, :file:`setup.py`, containing the above code and run:: + + python setup.py sdist + +which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +containing your setup script :file:`setup.py`, and your module :file:`foo.py`. +The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and +will unpack into a directory :file:`foo-1.0`. + +If an end-user wishes to install your :mod:`foo` module all he has to do is +download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and from the +:file:`foo-1.0` directory run :: + + python setup.py install + +which will copy :file:`foo.py` to the appropriate directory for +third-party modules in their Python installation. + +This simple example demonstrates some fundamental concepts of Distutils. +First, both developers and installers have the same basic user interface, i.e. +the setup script. The difference is which Distutils *commands* they use: the +:command:`sdist` command is almost exclusively for module developers, while +:command:`install` is more often used by installers (although some developers +will want to install their own code occasionally). + +If you want to make things really easy for your users, you can create more +than one built distributions for them. For instance, if you are running on a +Windows machine and want to make things easy for other Windows users, you can +create an executable installer (the most appropriate type of built distribution +for this platform) with the :command:`bdist_wininst` command. For example:: + + python setup.py bdist_wininst + +will create an executable installer, :file:`foo-1.0.win32.exe`, in the current +directory. You can find out what distribution formats are available at any time +by running :: + + python setup.py bdist --help-formats + + +.. _packaging-python-terms: + +General Python terminology +========================== + +If you're reading this document, you probably have a good idea of what Python +modules, extensions and so forth are. Nevertheless, just to be sure that +everyone is on the same page, here's a quick overview of Python terms: + +module + The basic unit of code reusability in Python: a block of code imported by + some other code. Three types of modules are important to us here: pure + Python modules, extension modules and packages. + +pure Python module + A module written in Python and contained in a single :file:`.py` file (and + possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes + referred to as a "pure module." + +extension module + A module written in the low-level language of the Python implementation: C/C++ + for Python, Java for Jython. Typically contained in a single dynamically + loaded pre-compiled file, e.g. a shared object (:file:`.so`) file for Python + extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python + extensions on Windows, or a Java class file for Jython extensions. Note that + currently Distutils only handles C/C++ extensions for Python. + +package + A module that contains other modules, typically contained in a directory of + the filesystem and distinguished from other directories by the presence of a + file :file:`__init__.py`. + +root package + The root of the hierarchy of packages. (This isn't really a package, + since it doesn't have an :file:`__init__.py` file. But... we have to + call it something, right?) The vast majority of the standard library is + in the root package, as are many small standalone third-party modules that + don't belong to a larger module collection. Unlike regular packages, + modules in the root package can be found in many directories: in fact, + every directory listed in ``sys.path`` contributes modules to the root + package. + + +.. _packaging-term: + +Distutils-specific terminology +============================== + +The following terms apply more specifically to the domain of distributing Python +modules using Distutils: + +module distribution + A collection of Python modules distributed together as a single downloadable + resource and meant to be installed all as one. Examples of some well-known + module distributions are NumPy, SciPy, PIL (the Python Imaging + Library) or mxBase. (Module distributions would be called a *package*, + except that term is already taken in the Python context: a single module + distribution may contain zero, one, or many Python packages.) + +pure module distribution + A module distribution that contains only pure Python modules and packages. + Sometimes referred to as a "pure distribution." + +non-pure module distribution + A module distribution that contains at least one extension module. Sometimes + referred to as a "non-pure distribution." + +distribution root + The top-level directory of your source tree (or source distribution). The + directory where :file:`setup.py` exists. Generally :file:`setup.py` will + be run from this directory. diff --git a/Doc/packaging/packageindex.rst b/Doc/packaging/packageindex.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/packageindex.rst @@ -0,0 +1,104 @@ +.. _packaging-package-index: + +********************************** +Registering with the Package Index +********************************** + +The Python Package Index (PyPI) holds metadata describing distributions +packaged with packaging. The packaging command :command:`register` is used to +submit your distribution's metadata to the index. It is invoked as follows:: + + python setup.py register + +Distutils will respond with the following prompt:: + + running register + We need to know who you are, so please choose either: + 1. use your existing login, + 2. register as a new user, + 3. have the server generate a new password for you (and email it to you), or + 4. quit + Your selection [default 1]: + +Note: if your username and password are saved locally, you will not see this +menu. + +If you have not registered with PyPI, then you will need to do so now. You +should choose option 2, and enter your details as required. Soon after +submitting your details, you will receive an email which will be used to confirm +your registration. + +Once you are registered, you may choose option 1 from the menu. You will be +prompted for your PyPI username and password, and :command:`register` will then +submit your metadata to the index. + +You may submit any number of versions of your distribution to the index. If you +alter the metadata for a particular version, you may submit it again and the +index will be updated. + +PyPI holds a record for each (name, version) combination submitted. The first +user to submit information for a given name is designated the Owner of that +name. They may submit changes through the :command:`register` command or through +the web interface. They may also designate other users as Owners or Maintainers. +Maintainers may edit the package information, but not designate other Owners or +Maintainers. + +By default PyPI will list all versions of a given package. To hide certain +versions, the Hidden property should be set to yes. This must be edited through +the web interface. + + +.. _packaging-pypirc: + +The .pypirc file +================ + +The format of the :file:`.pypirc` file is as follows:: + + [packaging] + index-servers = + pypi + + [pypi] + repository: + username: + password: + +The *packaging* section defines a *index-servers* variable that lists the +name of all sections describing a repository. + +Each section describing a repository defines three variables: + +- *repository*, that defines the url of the PyPI server. Defaults to + ``http://www.python.org/pypi``. +- *username*, which is the registered username on the PyPI server. +- *password*, that will be used to authenticate. If omitted the user + will be prompt to type it when needed. + +If you want to define another server a new section can be created and +listed in the *index-servers* variable:: + + [packaging] + index-servers = + pypi + other + + [pypi] + repository: + username: + password: + + [other] + repository: http://example.com/pypi + username: + password: + +:command:`register` can then be called with the -r option to point the +repository to work with:: + + python setup.py register -r http://example.com/pypi + +For convenience, the name of the section that describes the repository +may also be used:: + + python setup.py register -r other diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/setupcfg.rst @@ -0,0 +1,648 @@ +.. highlightlang:: cfg + +******************************************* +Specification of the :file:`setup.cfg` file +******************************************* + +.. :version: 1.0 + +This document describes the :file:`setup.cfg`, an ini-style configuration file +(compatible with :class:`configparser.RawConfigParser`) configuration file used +by Packaging to replace the :file:`setup.py` file. + +Each section contains a description of its options. + +- Options that are marked *multi* can have multiple values, one value per + line. +- Options that are marked *optional* can be omitted. +- Options that are marked *environ* can use environment markers, as described + in :PEP:`345`. + + +The sections are: + +global + Global options not related to one command. + +metadata + Name, version and other information defined by :PEP:`345`. + +files + Modules, scripts, data, documentation and other files to include in the + distribution. + +command sections + Options given for specific commands, identical to those that can be given + on the command line. + + +Global options +============== + +Contains global options for Packaging. This section is shared with Distutils. + + +commands + Defined Packaging command. A command is defined by its fully + qualified name. *optional*, *multi* + + Examples:: + + [global] + commands = + package.setup.CustomSdistCommand + package.setup.BdistDeb + +compilers + Defined Packaging compiler. A compiler is defined by its fully + qualified name. *optional*, *multi* + + Example:: + + [global] + compilers = + hotcompiler.SmartCCompiler + +setup_hook + defines a callable that will be called right after the + :file:`setup.cfg` file is read. The callable receives the configuration + in form of a mapping and can make some changes to it. *optional* + + Example:: + + [global] + setup_hook = package.setup.customize_dist + + +Metadata +======== + +The metadata section contains the metadata for the project as described in +:PEP:`345`. Field names are case-insensitive. + +Fields: + +name + Name of the project. + +version + Version of the project. Must comply with :PEP:`386`. + +platform + Platform specification describing an operating system + supported by the distribution which is not listed in the "Operating System" + Trove classifiers (:PEP:`301`). *optional*, *multi* + +supported-platform + Binary distributions containing a PKG-INFO file will + use the Supported-Platform field in their metadata to specify the OS and + CPU for which the binary distribution was compiled. The semantics of + the Supported-Platform field are free form. *optional*, *multi* + +summary + A one-line summary of what the distribution does. + (Used to be called *description* in Distutils1.) + +description + A longer description. (Used to be called *long_description* + in Distutils1.) A file can be provided in the *description-file* field. + *optional* + +description-file + path to a text file that will be used for the + **description** field. *optional* + +keywords + A list of additional keywords to be used to assist searching + for the distribution in a larger catalog. Comma or space-separated. + *optional* + +home-page + The URL for the distribution's home page. + +download-url + The URL from which this version of the distribution + can be downloaded. *optional* + +author + Author's name. *optional* + +author-email + Author's e-mail. *optional* + +maintainer + Maintainer's name. *optional* + +maintainer-email + Maintainer's e-mail. *optional* + +license + A text indicating the term of uses, when a trove classifier does + not match. *optional*. + +classifiers + Classification for the distribution, as described in PEP 301. + *optional*, *multi*, *environ* + +requires-dist + name of another packaging project required as a dependency. + The format is *name (version)* where version is an optional + version declaration, as described in PEP 345. *optional*, *multi*, *environ* + +provides-dist + name of another packaging project contained within this + distribution. Same format than *requires-dist*. *optional*, *multi*, + *environ* + +obsoletes-dist + name of another packaging project this version obsoletes. + Same format than *requires-dist*. *optional*, *multi*, *environ* + +requires-python + Specifies the Python version the distribution requires. + The value is a version number, as described in PEP 345. + *optional*, *multi*, *environ* + +requires-externals + a dependency in the system. This field is free-form, + and just a hint for downstream maintainers. *optional*, *multi*, + *environ* + +project-url + A label, followed by a browsable URL for the project. + "label, url". The label is limited to 32 signs. *optional*, *multi* + + +Example:: + + [metadata] + name = pypi2rpm + version = 0.1 + author = Tarek Ziad? + author-email = tarek at ziade.org + summary = Script that transforms an sdist archive into a RPM package + description-file = README + home-page = http://bitbucket.org/tarek/pypi2rpm/wiki/Home + project-url: + Repository, http://bitbucket.org/tarek/pypi2rpm/ + RSS feed, https://bitbucket.org/tarek/pypi2rpm/rss + classifier = + Development Status :: 3 - Alpha + License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1) + +You should not give any explicit value for metadata-version: it will be guessed +from the fields present in the file. + + +Files +===== + +This section describes the files included in the project. + +packages_root + the root directory containing all packages and modules + (default: current directory). *optional* + +packages + a list of packages the project includes *optional*, *multi* + +modules + a list of packages the project includes *optional*, *multi* + +scripts + a list of scripts the project includes *optional*, *multi* + +extra_files + a list of patterns to include extra files *optional*, + *multi* + +Example:: + + [files] + packages_root = src + packages = + pypi2rpm + pypi2rpm.command + + scripts = + pypi2rpm/pypi2rpm.py + + extra_files = + setup.py + README + + +.. Note:: + The :file:`setup.cfg` configuration file is included by default. Contrary to + Distutils, :file:`README` (or :file:`README.txt`) and :file:`setup.py` are + not included by default. + + +Resources +--------- + +This section describes the files used by the project which must not be installed +in the same place that python modules or libraries, they are called +**resources**. They are for example documentation files, script files, +databases, etc... + +For declaring resources, you must use this notation:: + + source = destination + +Data-files are declared in the **resources** field in the **file** section, for +example:: + + [files] + resources = + source1 = destination1 + source2 = destination2 + +The **source** part of the declaration are relative paths of resources files +(using unix path separator **/**). For example, if you've this source tree:: + + foo/ + doc/ + doc.man + scripts/ + foo.sh + +Your setup.cfg will look like:: + + [files] + resources = + doc/doc.man = destination_doc + scripts/foo.sh = destination_scripts + +The final paths where files will be placed are composed by : **source** + +**destination**. In the previous example, **doc/doc.man** will be placed in +**destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in +**destination_scripts/scripts/foo.sh**. (If you want more control on the final +path, take a look at base_prefix_). + +The **destination** part of resources declaration are paths with categories. +Indeed, it's generally a bad idea to give absolute path as it will be cross +incompatible. So, you must use resources categories in your **destination** +declaration. Categories will be replaced by their real path at the installation +time. Using categories is all benefit, your declaration will be simpler, cross +platform and it will allow packager to place resources files where they want +without breaking your code. + +Categories can be specified by using this syntax:: + + {category} + +Default categories are: + +* config +* appdata +* appdata.arch +* appdata.persistent +* appdata.disposable +* help +* icon +* scripts +* doc +* info +* man + +A special category also exists **{distribution.name}** that will be replaced by +the name of the distribution, but as most of the defaults categories use them, +so it's not necessary to add **{distribution.name}** into your destination. + +If you use categories in your declarations, and you are encouraged to do, final +path will be:: + + source + destination_expanded + +.. _example_final_path: + +For example, if you have this setup.cfg:: + + [metadata] + name = foo + + [files] + resources = + doc/doc.man = {doc} + +And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final +path will be:: + + {datadir}/doc/foo/doc/doc.man + +Where {datafir} category will be platform-dependent. + + +More control on source part +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Glob syntax +""""""""""" + +When you declare source file, you can use a glob-like syntax to match multiples file, for example:: + + scripts/* = {script} + +Will match all the files in the scripts directory and placed them in the script category. + +Glob tokens are: + + * ``*``: match all files. + * ``?``: match any character. + * ``**``: match any level of tree recursion (even 0). + * ``{}``: will match any part separated by comma (example: ``{sh,bat}``). + +.. TODO Add examples + +Order of declaration +"""""""""""""""""""" + +The order of declaration is important if one file match multiple rules. The last +rules matched by file is used, this is useful if you have this source tree:: + + foo/ + doc/ + index.rst + setup.rst + documentation.txt + doc.tex + README + +And you want all the files in the doc directory to be placed in {doc} category, +but README must be placed in {help} category, instead of listing all the files +one by one, you can declare them in this way:: + + [files] + resources = + doc/* = {doc} + doc/README = {help} + +Exclude +""""""" + +You can exclude some files of resources declaration by giving no destination, it +can be useful if you have a non-resources file in the same directory of +resources files:: + + foo/ + doc/ + RELEASES + doc.tex + documentation.txt + docu.rst + +Your **files** section will be:: + + [files] + resources = + doc/* = {doc} + doc/RELEASES = + +More control on destination part +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. _base_prefix: + +Defining a base prefix +"""""""""""""""""""""" + +When you define your resources, you can have more control of how the final path +is compute. + +By default, the final path is:: + + destination + source + +This can generate long paths, for example (example_final_path_):: + + {datadir}/doc/foo/doc/doc.man + +When you declare your source, you can use whitespace to split the source in +**prefix** **suffix**. So, for example, if you have this source:: + + docs/ doc.man + +The **prefix** is "docs/" and the **suffix** is "doc.html". + +.. note:: + + Separator can be placed after a path separator or replace it. So these two + sources are equivalent:: + + docs/ doc.man + docs doc.man + +.. note:: + + Glob syntax is working the same way with standard source and splitted source. + So these rules:: + + docs/* + docs/ * + docs * + + Will match all the files in the docs directory. + +When you use splitted source, the final path is compute in this way:: + + destination + prefix + +So for example, if you have this setup.cfg:: + + [metadata] + name = foo + + [files] + resources = + doc/ doc.man = {doc} + +And if **{doc}** is replaced by **{datadir}/doc/{distribution.name}**, final +path will be:: + + {datadir}/doc/foo/doc.man + + +Overwriting paths for categories +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This part is intended for system administrators or downstream OS packagers. + +The real paths of categories are registered in the *sysconfig.cfg* file +installed in your python installation. This file uses an ini format too. +The content of the file is organized into several sections: + +* globals: Standard categories's paths. +* posix_prefix: Standard paths for categories and installation paths for posix + system. +* other ones XXX + +Standard categories paths are platform independent, they generally refers to +other categories, which are platform dependent. :mod:`sysconfig` will choose +these category from sections matching os.name. For example:: + + doc = {datadir}/doc/{distribution.name} + +It refers to datadir category, which can be different between platforms. In +posix system, it may be:: + + datadir = /usr/share + +So the final path will be:: + + doc = /usr/share/doc/{distribution.name} + +The platform-dependent categories are: + +* confdir +* datadir +* libdir +* base + + +Defining extra categories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. TODO + + +Examples +^^^^^^^^ + +These examples are incremental but work unitarily. + +Resources in root dir +""""""""""""""""""""" + +Source tree:: + + babar-1.0/ + README + babar.sh + launch.sh + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + *.sh = {scripts} + +So babar.sh and launch.sh will be placed in {scripts} directory. + +Now let's move all the scripts into a scripts directory. + +Resources in sub-directory +"""""""""""""""""""""""""" + +Source tree:: + + babar-1.1/ + README + scripts/ + babar.sh + launch.sh + LAUNCH + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.sh = {scripts} + +It's important to use the separator after scripts/ to install all the shell +scripts into {scripts} instead of {scripts}/scripts. + +Now let's add some docs. + +Resources in multiple sub-directories +""""""""""""""""""""""""""""""""""""" + +Source tree:: + + babar-1.2/ + README + scripts/ + babar.sh + launch.sh + LAUNCH + docs/ + api + man + babar.py + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.sh = {scripts} + doc/ * = {doc} + doc/ man = {man} + +You want to place all the file in the docs script into {doc} category, instead +of man, which must be placed into {man} category, we will use the order of +declaration of globs to choose the destination, the last glob that match the +file is used. + +Now let's add some scripts for windows users. + +Complete example +"""""""""""""""" + +Source tree:: + + babar-1.3/ + README + doc/ + api + man + scripts/ + babar.sh + launch.sh + babar.bat + launch.bat + LAUNCH + +:file:`setup.cfg`:: + + [files] + resources = + README = {doc} + scripts/ LAUNCH = {doc} + scripts/ *.{sh,bat} = {scripts} + doc/ * = {doc} + doc/ man = {man} + +We use brace expansion syntax to place all the shell and batch scripts into +{scripts} category. + + +Command sections +================ + +To pass options to commands without having to type them on the command line +for each invocation, you can write them in the :file:`setup.cfg` file, in a +section named after the command. Example:: + + [sdist] + # special function to add custom files + manifest-builders = package.setup.list_extra_files + + [build] + use-2to3 = True + + [build_ext] + inplace = on + + [check] + strict = on + all = on + +Option values given in the configuration file can be overriden on the command +line. See :ref:`packaging-setup-config` for more information. diff --git a/Doc/packaging/setupscript.rst b/Doc/packaging/setupscript.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/setupscript.rst @@ -0,0 +1,689 @@ +.. _packaging-setup-script: + +************************ +Writing the Setup Script +************************ + +The setup script is the center of all activity in building, distributing, and +installing modules using Distutils. The main purpose of the setup script is +to describe your module distribution to Distutils, so that the various +commands that operate on your modules do the right thing. As we saw in section +:ref:`packaging-simple-example`, the setup script consists mainly of a +call to :func:`setup` where the most information is supplied as +keyword arguments to :func:`setup`. + +Here's a slightly more involved example, which we'll follow for the next couple +of sections: a setup script that could be used for Packaging itself:: + + #!/usr/bin/env python + + from packaging.core import setup, find_packages + + setup(name='Packaging', + version='1.0', + summary='Python Distribution Utilities', + keywords=['packaging', 'packaging'], + author=u'Tarek Ziad?', + author_email='tarek at ziade.org', + home_page='http://bitbucket.org/tarek/packaging/wiki/Home', + license='PSF', + packages=find_packages()) + + +There are only two differences between this and the trivial one-file +distribution presented in section :ref:`packaging-simple-example`: more +metadata and the specification of pure Python modules by package rather than +by module. This is important since Ristutils consist of a couple of dozen +modules split into (so far) two packages; an explicit list of every module +would be tedious to generate and difficult to maintain. For more information +on the additional metadata, see section :ref:`packaging-metadata`. + +Note that any pathnames (files or directories) supplied in the setup script +should be written using the Unix convention, i.e. slash-separated. The +Distutils will take care of converting this platform-neutral representation into +whatever is appropriate on your current platform before actually using the +pathname. This makes your setup script portable across operating systems, which +of course is one of the major goals of the Distutils. In this spirit, all +pathnames in this document are slash-separated. + +This, of course, only applies to pathnames given to Distutils functions. If +you, for example, use standard Python functions such as :func:`glob.glob` or +:func:`os.listdir` to specify files, you should be careful to write portable +code instead of hardcoding path separators:: + + glob.glob(os.path.join('mydir', 'subdir', '*.html')) + os.listdir(os.path.join('mydir', 'subdir')) + + +.. _packaging-listing-packages: + +Listing whole packages +====================== + +The :option:`packages` option tells the Distutils to process (build, distribute, +install, etc.) all pure Python modules found in each package mentioned in the +:option:`packages` list. In order to do this, of course, there has to be a +correspondence between package names and directories in the filesystem. The +default correspondence is the most obvious one, i.e. package :mod:`packaging` is +found in the directory :file:`packaging` relative to the distribution root. +Thus, when you say ``packages = ['foo']`` in your setup script, you are +promising that the Distutils will find a file :file:`foo/__init__.py` (which +might be spelled differently on your system, but you get the idea) relative to +the directory where your setup script lives. If you break this promise, the +Distutils will issue a warning but still process the broken package anyways. + +If you use a different convention to lay out your source directory, that's no +problem: you just have to supply the :option:`package_dir` option to tell the +Distutils about your convention. For example, say you keep all Python source +under :file:`lib`, so that modules in the "root package" (i.e., not in any +package at all) are in :file:`lib`, modules in the :mod:`foo` package are in +:file:`lib/foo`, and so forth. Then you would put :: + + package_dir = {'': 'lib'} + +in your setup script. The keys to this dictionary are package names, and an +empty package name stands for the root package. The values are directory names +relative to your distribution root. In this case, when you say ``packages = +['foo']``, you are promising that the file :file:`lib/foo/__init__.py` exists. + +Another possible convention is to put the :mod:`foo` package right in +:file:`lib`, the :mod:`foo.bar` package in :file:`lib/bar`, etc. This would be +written in the setup script as :: + + package_dir = {'foo': 'lib'} + +A ``package: dir`` entry in the :option:`package_dir` dictionary implicitly +applies to all packages below *package*, so the :mod:`foo.bar` case is +automatically handled here. In this example, having ``packages = ['foo', +'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and +:file:`lib/bar/__init__.py`. (Keep in mind that although :option:`package_dir` +applies recursively, you must explicitly list all packages in +:option:`packages`: the Distutils will *not* recursively scan your source tree +looking for any directory with an :file:`__init__.py` file.) + + +.. _packaging-listing-modules: + +Listing individual modules +========================== + +For a small module distribution, you might prefer to list all modules rather +than listing packages---especially the case of a single module that goes in the +"root package" (i.e., no package at all). This simplest case was shown in +section :ref:`packaging-simple-example`; here is a slightly more involved +example:: + + py_modules = ['mod1', 'pkg.mod2'] + +This describes two modules, one of them in the "root" package, the other in the +:mod:`pkg` package. Again, the default package/directory layout implies that +these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and +that :file:`pkg/__init__.py` exists as well. And again, you can override the +package/directory correspondence using the :option:`package_dir` option. + + +.. _packaging-describing-extensions: + +Describing extension modules +============================ + +Just as writing Python extension modules is a bit more complicated than writing +pure Python modules, describing them to the Distutils is a bit more complicated. +Unlike pure modules, it's not enough just to list modules or packages and expect +the Distutils to go out and find the right files; you have to specify the +extension name, source file(s), and any compile/link requirements (include +directories, libraries to link with, etc.). + +.. XXX read over this section + +All of this is done through another keyword argument to :func:`setup`, the +:option:`ext_modules` option. :option:`ext_modules` is just a list of +:class:`Extension` instances, each of which describes a single extension module. +Suppose your distribution includes a single extension, called :mod:`foo` and +implemented by :file:`foo.c`. If no additional instructions to the +compiler/linker are needed, describing this extension is quite simple:: + + Extension('foo', ['foo.c']) + +The :class:`Extension` class can be imported from :mod:`packaging.core` along +with :func:`setup`. Thus, the setup script for a module distribution that +contains only this one extension and nothing else might be:: + + from packaging.core import setup, Extension + setup(name='foo', + version='1.0', + ext_modules=[Extension('foo', ['foo.c'])]) + +The :class:`Extension` class (actually, the underlying extension-building +machinery implemented by the :command:`build_ext` command) supports a great deal +of flexibility in describing Python extensions, which is explained in the +following sections. + + +Extension names and packages +---------------------------- + +The first argument to the :class:`Extension` constructor is always the name of +the extension, including any package names. For example, :: + + Extension('foo', ['src/foo1.c', 'src/foo2.c']) + +describes an extension that lives in the root package, while :: + + Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c']) + +describes the same extension in the :mod:`pkg` package. The source files and +resulting object code are identical in both cases; the only difference is where +in the filesystem (and therefore where in Python's namespace hierarchy) the +resulting extension lives. + +If you have a number of extensions all in the same package (or all under the +same base package), use the :option:`ext_package` keyword argument to +:func:`setup`. For example, :: + + setup(..., + ext_package='pkg', + ext_modules=[Extension('foo', ['foo.c']), + Extension('subpkg.bar', ['bar.c'])]) + +will compile :file:`foo.c` to the extension :mod:`pkg.foo`, and :file:`bar.c` to +:mod:`pkg.subpkg.bar`. + + +Extension source files +---------------------- + +The second argument to the :class:`Extension` constructor is a list of source +files. Since the Distutils currently only support C, C++, and Objective-C +extensions, these are normally C/C++/Objective-C source files. (Be sure to use +appropriate extensions to distinguish C++\ source files: :file:`.cc` and +:file:`.cpp` seem to be recognized by both Unix and Windows compilers.) + +However, you can also include SWIG interface (:file:`.i`) files in the list; the +:command:`build_ext` command knows how to deal with SWIG extensions: it will run +SWIG on the interface file and compile the resulting C/C++ file into your +extension. + +.. XXX SWIG support is rough around the edges and largely untested! + +This warning notwithstanding, options to SWIG can be currently passed like +this:: + + setup(..., + ext_modules=[Extension('_foo', ['foo.i'], + swig_opts=['-modern', '-I../include'])], + py_modules=['foo']) + +Or on the command line like this:: + + > python setup.py build_ext --swig-opts="-modern -I../include" + +On some platforms, you can include non-source files that are processed by the +compiler and included in your extension. Currently, this just means Windows +message text (:file:`.mc`) files and resource definition (:file:`.rc`) files for +Visual C++. These will be compiled to binary resource (:file:`.res`) files and +linked into the executable. + + +Preprocessor options +-------------------- + +Three optional arguments to :class:`Extension` will help if you need to specify +include directories to search or preprocessor macros to define/undefine: +``include_dirs``, ``define_macros``, and ``undef_macros``. + +For example, if your extension requires header files in the :file:`include` +directory under your distribution root, use the ``include_dirs`` option:: + + Extension('foo', ['foo.c'], include_dirs=['include']) + +You can specify absolute directories there; if you know that your extension will +only be built on Unix systems with X11R6 installed to :file:`/usr`, you can get +away with :: + + Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11']) + +You should avoid this sort of non-portable usage if you plan to distribute your +code: it's probably better to write C code like :: + + #include + +If you need to include header files from some other Python extension, you can +take advantage of the fact that header files are installed in a consistent way +by the Distutils :command:`install_header` command. For example, the Numerical +Python header files are installed (on a standard Unix installation) to +:file:`/usr/local/include/python1.5/Numerical`. (The exact location will differ +according to your platform and Python installation.) Since the Python include +directory---\ :file:`/usr/local/include/python1.5` in this case---is always +included in the search path when building Python extensions, the best approach +is to write C code like :: + + #include + +.. TODO check if it's d2.sysconfig or the new sysconfig module now + +If you must put the :file:`Numerical` include directory right into your header +search path, though, you can find that directory using the Distutils +:mod:`packaging.sysconfig` module:: + + from packaging.sysconfig import get_python_inc + incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical') + setup(..., + Extension(..., include_dirs=[incdir])) + +Even though this is quite portable---it will work on any Python installation, +regardless of platform---it's probably easier to just write your C code in the +sensible way. + +You can define and undefine preprocessor macros with the ``define_macros`` and +``undef_macros`` options. ``define_macros`` takes a list of ``(name, value)`` +tuples, where ``name`` is the name of the macro to define (a string) and +``value`` is its value: either a string or ``None``. (Defining a macro ``FOO`` +to ``None`` is the equivalent of a bare ``#define FOO`` in your C source: with +most compilers, this sets ``FOO`` to the string ``1``.) ``undef_macros`` is +just a list of macros to undefine. + +For example:: + + Extension(..., + define_macros=[('NDEBUG', '1'), + ('HAVE_STRFTIME', None)], + undef_macros=['HAVE_FOO', 'HAVE_BAR']) + +is the equivalent of having this at the top of every C source file:: + + #define NDEBUG 1 + #define HAVE_STRFTIME + #undef HAVE_FOO + #undef HAVE_BAR + + +Library options +--------------- + +You can also specify the libraries to link against when building your extension, +and the directories to search for those libraries. The ``libraries`` option is +a list of libraries to link against, ``library_dirs`` is a list of directories +to search for libraries at link-time, and ``runtime_library_dirs`` is a list of +directories to search for shared (dynamically loaded) libraries at run-time. + +For example, if you need to link against libraries known to be in the standard +library search path on target systems :: + + Extension(..., + libraries=['gdbm', 'readline']) + +If you need to link with libraries in a non-standard location, you'll have to +include the location in ``library_dirs``:: + + Extension(..., + library_dirs=['/usr/X11R6/lib'], + libraries=['X11', 'Xt']) + +(Again, this sort of non-portable construct should be avoided if you intend to +distribute your code.) + +.. XXX Should mention clib libraries here or somewhere else! + + +Other options +------------- + +There are still some other options which can be used to handle special cases. + +The :option:`optional` option is a boolean; if it is true, +a build failure in the extension will not abort the build process, but +instead simply not install the failing extension. + +The :option:`extra_objects` option is a list of object files to be passed to the +linker. These files must not have extensions, as the default extension for the +compiler is used. + +:option:`extra_compile_args` and :option:`extra_link_args` can be used to +specify additional command-line options for the respective compiler and linker +command lines. + +:option:`export_symbols` is only useful on Windows. It can contain a list of +symbols (functions or variables) to be exported. This option is not needed when +building compiled extensions: Distutils will automatically add ``initmodule`` +to the list of exported symbols. + +The :option:`depends` option is a list of files that the extension depends on +(for example header files). The build command will call the compiler on the +sources to rebuild extension if any on this files has been modified since the +previous build. + +Relationships between Distributions and Packages +================================================ + +.. FIXME rewrite to update to PEP 345 (but without dist/release confusion) + +A distribution may relate to packages in three specific ways: + +#. It can require packages or modules. + +#. It can provide packages or modules. + +#. It can obsolete packages or modules. + +These relationships can be specified using keyword arguments to the +:func:`packaging.core.setup` function. + +Dependencies on other Python modules and packages can be specified by supplying +the *requires* keyword argument to :func:`setup`. The value must be a list of +strings. Each string specifies a package that is required, and optionally what +versions are sufficient. + +To specify that any version of a module or package is required, the string +should consist entirely of the module or package name. Examples include +``'mymodule'`` and ``'xml.parsers.expat'``. + +If specific versions are required, a sequence of qualifiers can be supplied in +parentheses. Each qualifier may consist of a comparison operator and a version +number. The accepted comparison operators are:: + + < > == + <= >= != + +These can be combined by using multiple qualifiers separated by commas (and +optional whitespace). In this case, all of the qualifiers must be matched; a +logical AND is used to combine the evaluations. + +Let's look at a bunch of examples: + ++-------------------------+----------------------------------------------+ +| Requires Expression | Explanation | ++=========================+==============================================+ +| ``==1.0`` | Only version ``1.0`` is compatible | ++-------------------------+----------------------------------------------+ +| ``>1.0, !=1.5.1, <2.0`` | Any version after ``1.0`` and before ``2.0`` | +| | is compatible, except ``1.5.1`` | ++-------------------------+----------------------------------------------+ + +Now that we can specify dependencies, we also need to be able to specify what we +provide that other distributions can require. This is done using the *provides* +keyword argument to :func:`setup`. The value for this keyword is a list of +strings, each of which names a Python module or package, and optionally +identifies the version. If the version is not specified, it is assumed to match +that of the distribution. + +Some examples: + ++---------------------+----------------------------------------------+ +| Provides Expression | Explanation | ++=====================+==============================================+ +| ``mypkg`` | Provide ``mypkg``, using the distribution | +| | version | ++---------------------+----------------------------------------------+ +| ``mypkg (1.1)`` | Provide ``mypkg`` version 1.1, regardless of | +| | the distribution version | ++---------------------+----------------------------------------------+ + +A package can declare that it obsoletes other packages using the *obsoletes* +keyword argument. The value for this is similar to that of the *requires* +keyword: a list of strings giving module or package specifiers. Each specifier +consists of a module or package name optionally followed by one or more version +qualifiers. Version qualifiers are given in parentheses after the module or +package name. + +The versions identified by the qualifiers are those that are obsoleted by the +distribution being described. If no qualifiers are given, all versions of the +named module or package are understood to be obsoleted. + +.. _packaging-installing-scripts: + +Installing Scripts +================== + +So far we have been dealing with pure and non-pure Python modules, which are +usually not run by themselves but imported by scripts. + +Scripts are files containing Python source code, intended to be started from the +command line. Scripts don't require Distutils to do anything very complicated. +The only clever feature is that if the first line of the script starts with +``#!`` and contains the word "python", the Distutils will adjust the first line +to refer to the current interpreter location. By default, it is replaced with +the current interpreter location. The :option:`--executable` (or :option:`-e`) +option will allow the interpreter path to be explicitly overridden. + +The :option:`scripts` option simply is a list of files to be handled in this +way. From the PyXML setup script:: + + setup(..., + scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']) + +All the scripts will also be added to the ``MANIFEST`` file if no template is +provided. See :ref:`packaging-manifest`. + +.. _packaging-installing-package-data: + +Installing Package Data +======================= + +Often, additional files need to be installed into a package. These files are +often data that's closely related to the package's implementation, or text files +containing documentation that might be of interest to programmers using the +package. These files are called :dfn:`package data`. + +Package data can be added to packages using the ``package_data`` keyword +argument to the :func:`setup` function. The value must be a mapping from +package name to a list of relative path names that should be copied into the +package. The paths are interpreted as relative to the directory containing the +package (information from the ``package_dir`` mapping is used if appropriate); +that is, the files are expected to be part of the package in the source +directories. They may contain glob patterns as well. + +The path names may contain directory portions; any necessary directories will be +created in the installation. + +For example, if a package should contain a subdirectory with several data files, +the files can be arranged like this in the source tree:: + + setup.py + src/ + mypkg/ + __init__.py + module.py + data/ + tables.dat + spoons.dat + forks.dat + +The corresponding call to :func:`setup` might be:: + + setup(..., + packages=['mypkg'], + package_dir={'mypkg': 'src/mypkg'}, + package_data={'mypkg': ['data/*.dat']}) + + +All the files that match ``package_data`` will be added to the ``MANIFEST`` +file if no template is provided. See :ref:`packaging-manifest`. + + +.. _packaging-additional-files: + +Installing Additional Files +=========================== + +The :option:`data_files` option can be used to specify additional files needed +by the module distribution: configuration files, message catalogs, data files, +anything which doesn't fit in the previous categories. + +:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the +following way:: + + setup(..., + data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), + ('config', ['cfg/data.cfg']), + ('/etc/init.d', ['init-script'])]) + +Note that you can specify the directory names where the data files will be +installed, but you cannot rename the data files themselves. + +Each (*directory*, *files*) pair in the sequence specifies the installation +directory and the files to install there. If *directory* is a relative path, it +is interpreted relative to the installation prefix (Python's ``sys.prefix`` for +pure-Python packages, ``sys.exec_prefix`` for packages that contain extension +modules). Each file name in *files* is interpreted relative to the +:file:`setup.py` script at the top of the package source distribution. No +directory information from *files* is used to determine the final location of +the installed file; only the name of the file is used. + +You can specify the :option:`data_files` options as a simple sequence of files +without specifying a target directory, but this is not recommended, and the +:command:`install_dist` command will print a warning in this case. To install data +files directly in the target directory, an empty string should be given as the +directory. + +All the files that match ``data_files`` will be added to the ``MANIFEST`` file +if no template is provided. See :ref:`packaging-manifest`. + + + +.. _packaging-metadata: + +Metadata reference +================== + +The setup script may include additional metadata beyond the name and version. +This table describes required and additional information: + +.. TODO synchronize with setupcfg; link to it (but don't remove it, it's a + useful summary) + ++----------------------+---------------------------+-----------------+--------+ +| Meta-Data | Description | Value | Notes | ++======================+===========================+=================+========+ +| ``name`` | name of the project | short string | \(1) | ++----------------------+---------------------------+-----------------+--------+ +| ``version`` | version of this release | short string | (1)(2) | ++----------------------+---------------------------+-----------------+--------+ +| ``author`` | project author's name | short string | \(3) | ++----------------------+---------------------------+-----------------+--------+ +| ``author_email`` | email address of the | email address | \(3) | +| | project author | | | ++----------------------+---------------------------+-----------------+--------+ +| ``maintainer`` | project maintainer's name | short string | \(3) | ++----------------------+---------------------------+-----------------+--------+ +| ``maintainer_email`` | email address of the | email address | \(3) | +| | project maintainer | | | ++----------------------+---------------------------+-----------------+--------+ +| ``home_page`` | home page for the project | URL | \(1) | ++----------------------+---------------------------+-----------------+--------+ +| ``summary`` | short description of the | short string | | +| | project | | | ++----------------------+---------------------------+-----------------+--------+ +| ``description`` | longer description of the | long string | \(5) | +| | project | | | ++----------------------+---------------------------+-----------------+--------+ +| ``download_url`` | location where the | URL | | +| | project may be downloaded | | | ++----------------------+---------------------------+-----------------+--------+ +| ``classifiers`` | a list of classifiers | list of strings | \(4) | ++----------------------+---------------------------+-----------------+--------+ +| ``platforms`` | a list of platforms | list of strings | | ++----------------------+---------------------------+-----------------+--------+ +| ``license`` | license for the release | short string | \(6) | ++----------------------+---------------------------+-----------------+--------+ + +Notes: + +(1) + These fields are required. + +(2) + It is recommended that versions take the form *major.minor[.patch[.sub]]*. + +(3) + Either the author or the maintainer must be identified. + +(4) + The list of classifiers is available from the `PyPI website + `_. See also :mod:`packaging.create`. + +(5) + The ``description`` field is used by PyPI when you are registering a + release, to build its PyPI page. + +(6) + The ``license`` field is a text indicating the license covering the + distribution where the license is not a selection from the "License" Trove + classifiers. See the ``Classifier`` field. Notice that + there's a ``licence`` distribution option which is deprecated but still + acts as an alias for ``license``. + +'short string' + A single line of text, not more than 200 characters. + +'long string' + Multiple lines of plain text in reStructuredText format (see + http://docutils.sf.net/). + +'list of strings' + See below. + +In Python 2.x, "string value" means a unicode object. If a byte string (str or +bytes) is given, it has to be valid ASCII. + +.. TODO move this section to the version document, keep a summary, add a link + +Encoding the version information is an art in itself. Python projects generally +adhere to the version format *major.minor[.patch][sub]*. The major number is 0 +for initial, experimental releases of software. It is incremented for releases +that represent major milestones in a project. The minor number is incremented +when important new features are added to the project. The patch number +increments when bug-fix releases are made. Additional trailing version +information is sometimes used to indicate sub-releases. These are +"a1,a2,...,aN" (for alpha releases, where functionality and API may change), +"b1,b2,...,bN" (for beta releases, which only fix bugs) and "pr1,pr2,...,prN" +(for final pre-release release testing). Some examples: + +0.1.0 + the first, experimental release of a project + +1.0.1a2 + the second alpha release of the first patch version of 1.0 + +:option:`classifiers` are specified in a Python list:: + + setup(..., + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: Web Environment', + 'Intended Audience :: End Users/Desktop', + 'Intended Audience :: Developers', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Python Software Foundation License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Programming Language :: Python', + 'Topic :: Communications :: Email', + 'Topic :: Office/Business', + 'Topic :: Software Development :: Bug Tracking', + ]) + + +Debugging the setup script +========================== + +Sometimes things go wrong, and the setup script doesn't do what the developer +wants. + +Distutils catches any exceptions when running the setup script, and print a +simple error message before the script is terminated. The motivation for this +behaviour is to not confuse administrators who don't know much about Python and +are trying to install a project. If they get a big long traceback from deep +inside the guts of Distutils, they may think the project or the Python +installation is broken because they don't read all the way down to the bottom +and see that it's a permission problem. + +.. FIXME DISTUTILS_DEBUG is dead, document logging/warnings here + +On the other hand, this doesn't help the developer to find the cause of the +failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set +to anything except an empty string, and Packaging will now print detailed +information about what it is doing, and prints the full traceback in case an +exception occurs. diff --git a/Doc/packaging/sourcedist.rst b/Doc/packaging/sourcedist.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/sourcedist.rst @@ -0,0 +1,273 @@ +.. _packaging-source-dist: + +****************************** +Creating a Source Distribution +****************************** + +As shown in section :ref:`packaging-simple-example`, you use the :command:`sdist` command +to create a source distribution. In the simplest case, :: + + python setup.py sdist + +(assuming you haven't specified any :command:`sdist` options in the setup script +or config file), :command:`sdist` creates the archive of the default format for +the current platform. The default format is a gzip'ed tar file +(:file:`.tar.gz`) on Unix, and ZIP file on Windows. + +You can specify as many formats as you like using the :option:`--formats` +option, for example:: + + python setup.py sdist --formats=gztar,zip + +to create a gzipped tarball and a zip file. The available formats are: + ++-----------+-------------------------+---------+ +| Format | Description | Notes | ++===========+=========================+=========+ +| ``zip`` | zip file (:file:`.zip`) | (1),(3) | ++-----------+-------------------------+---------+ +| ``gztar`` | gzip'ed tar file | \(2) | +| | (:file:`.tar.gz`) | | ++-----------+-------------------------+---------+ +| ``bztar`` | bzip2'ed tar file | | +| | (:file:`.tar.bz2`) | | ++-----------+-------------------------+---------+ +| ``ztar`` | compressed tar file | \(4) | +| | (:file:`.tar.Z`) | | ++-----------+-------------------------+---------+ +| ``tar`` | tar file (:file:`.tar`) | | ++-----------+-------------------------+---------+ + +Notes: + +(1) + default on Windows + +(2) + default on Unix + +(3) + requires either external :program:`zip` utility or :mod:`zipfile` module (part + of the standard Python library since Python 1.6) + +(4) + requires the :program:`compress` program. Notice that this format is now + pending for deprecation and will be removed in the future versions of Python. + +When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or +``tar``) under Unix, you can specify the ``owner`` and ``group`` names +that will be set for each member of the archive. + +For example, if you want all files of the archive to be owned by root:: + + python setup.py sdist --owner=root --group=root + + +.. _packaging-manifest: + +Specifying the files to distribute +================================== + +If you don't supply an explicit list of files (or instructions on how to +generate one), the :command:`sdist` command puts a minimal default set into the +source distribution: + +* all Python source files implied by the :option:`py_modules` and + :option:`packages` options + +* all C source files mentioned in the :option:`ext_modules` or + :option:`libraries` options + +* scripts identified by the :option:`scripts` option + See :ref:`packaging-installing-scripts`. + +* anything that looks like a test script: :file:`test/test\*.py` (currently, the + Packaging don't do anything with test scripts except include them in source + distributions, but in the future there will be a standard for testing Python + module distributions) + +* the configuration file :file:`setup.cfg` + +* all files that matches the ``package_data`` metadata. + See :ref:`packaging-installing-package-data`. + +* all files that matches the ``data_files`` metadata. + See :ref:`packaging-additional-files`. + +Contrary to Distutils, :file:`README` (or :file:`README.txt`) and +:file:`setup.py` are not included by default. + +Sometimes this is enough, but usually you will want to specify additional files +to distribute. The typical way to do this is to write a *manifest template*, +called :file:`MANIFEST.in` by default. The manifest template is just a list of +instructions for how to generate your manifest file, :file:`MANIFEST`, which is +the exact list of files to include in your source distribution. The +:command:`sdist` command processes this template and generates a manifest based +on its instructions and what it finds in the filesystem. + +If you prefer to roll your own manifest file, the format is simple: one filename +per line, regular files (or symlinks to them) only. If you do supply your own +:file:`MANIFEST`, you must specify everything: the default set of files +described above does not apply in this case. + +:file:`MANIFEST` files start with a comment indicating they are generated. +Files without this comment are not overwritten or removed. + +See :ref:`packaging-manifest-template` section for a syntax reference. + + +.. _packaging-manifest-options: + +Manifest-related options +======================== + +The normal course of operations for the :command:`sdist` command is as follows: + +* if the manifest file, :file:`MANIFEST` doesn't exist, read :file:`MANIFEST.in` + and create the manifest + +* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest + with just the default file set + +* if either :file:`MANIFEST.in` or the setup script (:file:`setup.py`) are more + recent than :file:`MANIFEST`, recreate :file:`MANIFEST` by reading + :file:`MANIFEST.in` + +* use the list of files now in :file:`MANIFEST` (either just generated or read + in) to create the source distribution archive(s) + +There are a couple of options that modify this behaviour. First, use the +:option:`--no-defaults` and :option:`--no-prune` to disable the standard +"include" and "exclude" sets. + +Second, you might just want to (re)generate the manifest, but not create a +source distribution:: + + python setup.py sdist --manifest-only + +:option:`-o` is a shortcut for :option:`--manifest-only`. + + +.. _packaging-manifest-template: + +The MANIFEST.in template +======================== + +A :file:`MANIFEST.in` file can be added in a project to define the list of +files to include in the distribution built by the :command:`sdist` command. + +When :command:`sdist` is run, it will look for the :file:`MANIFEST.in` file +and interpret it to generate the :file:`MANIFEST` file that contains the +list of files that will be included in the package. + +This mechanism can be used when the default list of files is not enough. +(See :ref:`packaging-manifest`). + +Principle +--------- + +The manifest template has one command per line, where each command specifies a +set of files to include or exclude from the source distribution. For an +example, let's look at the Packaging' own manifest template:: + + include *.txt + recursive-include examples *.txt *.py + prune examples/sample?/build + +The meanings should be fairly clear: include all files in the distribution root +matching :file:`\*.txt`, all files anywhere under the :file:`examples` directory +matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching +:file:`examples/sample?/build`. All of this is done *after* the standard +include set, so you can exclude files from the standard set with explicit +instructions in the manifest template. (Or, you can use the +:option:`--no-defaults` option to disable the standard set entirely.) + +The order of commands in the manifest template matters: initially, we have the +list of default files as described above, and each command in the template adds +to or removes from that list of files. Once we have fully processed the +manifest template, we remove files that should not be included in the source +distribution: + +* all files in the Packaging "build" tree (default :file:`build/`) + +* all files in directories named :file:`RCS`, :file:`CVS`, :file:`.svn`, + :file:`.hg`, :file:`.git`, :file:`.bzr` or :file:`_darcs` + +Now we have our complete list of files, which is written to the manifest for +future reference, and then used to build the source distribution archive(s). + +You can disable the default set of included files with the +:option:`--no-defaults` option, and you can disable the standard exclude set +with :option:`--no-prune`. + +Following the Packaging' own manifest template, let's trace how the +:command:`sdist` command builds the list of files to include in the Packaging +source distribution: + +#. include all Python source files in the :file:`packaging` and + :file:`packaging/command` subdirectories (because packages corresponding to + those two directories were mentioned in the :option:`packages` option in the + setup script---see section :ref:`packaging-setup-script`) + +#. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard + files) + +#. include :file:`test/test\*.py` (standard files) + +#. include :file:`\*.txt` in the distribution root (this will find + :file:`README.txt` a second time, but such redundancies are weeded out later) + +#. include anything matching :file:`\*.txt` or :file:`\*.py` in the sub-tree + under :file:`examples`, + +#. exclude all files in the sub-trees starting at directories matching + :file:`examples/sample?/build`\ ---this may exclude files included by the + previous two steps, so it's important that the ``prune`` command in the manifest + template comes after the ``recursive-include`` command + +#. exclude the entire :file:`build` tree, and any :file:`RCS`, :file:`CVS`, + :file:`.svn`, :file:`.hg`, :file:`.git`, :file:`.bzr` and :file:`_darcs` + directories + +Just like in the setup script, file and directory names in the manifest template +should always be slash-separated; the Packaging will take care of converting +them to the standard representation on your platform. That way, the manifest +template is portable across operating systems. + +Commands +-------- + +The manifest template commands are: + ++-------------------------------------------+-----------------------------------------------+ +| Command | Description | ++===========================================+===============================================+ +| :command:`include pat1 pat2 ...` | include all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | +| | patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | +| ...` | the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | +| | matching --- & any of the listed patterns | ++-------------------------------------------+-----------------------------------------------+ +| :command:`prune dir` | exclude all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ +| :command:`graft dir` | include all files under *dir* | ++-------------------------------------------+-----------------------------------------------+ + +The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of +regular filename characters, ``?`` matches any single regular filename +character, and ``[range]`` matches any of the characters in *range* (e.g., +``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename +character" is platform-specific: on Unix it is anything except slash; on Windows +anything except backslash or colon. diff --git a/Doc/packaging/tutorial.rst b/Doc/packaging/tutorial.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/tutorial.rst @@ -0,0 +1,112 @@ +================== +Packaging tutorial +================== + +Welcome to the Packaging tutorial! We will learn how to use Packaging +to package your project. + +.. TODO merge with introduction.rst + + +Getting started +--------------- + +Packaging works with the *setup.cfg* file. It contains all the metadata for +your project, as defined in PEP 345, but also declare what your project +contains. + +Let's say you have a project called *CLVault* containing one package called +*clvault*, and a few scripts inside. You can use the *pysetup* script to create +a *setup.cfg* file for the project. The script will ask you a few questions:: + + $ mkdir CLVault + $ cd CLVault + $ pysetup create + Project name [CLVault]: + Current version number: 0.1 + Package description: + >Command-line utility to store and retrieve passwords + Author name: Tarek Ziade + Author e-mail address: tarek at ziade.org + Project Home Page: http://bitbucket.org/tarek/clvault + Do you want to add a package ? (y/n): y + Package name: clvault + Do you want to add a package ? (y/n): n + Do you want to set Trove classifiers? (y/n): y + Please select the project status: + + 1 - Planning + 2 - Pre-Alpha + 3 - Alpha + 4 - Beta + 5 - Production/Stable + 6 - Mature + 7 - Inactive + + Status: 3 + What license do you use: GPL + Matching licenses: + + 1) License :: OSI Approved :: GNU General Public License (GPL) + 2) License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) + + Type the number of the license you wish to use or ? to try again:: 1 + Do you want to set other trove identifiers (y/n) [n]: n + Wrote "setup.cfg". + + +A setup.cfg file is created, containing the metadata of your project and the +list of the packages it contains:: + + $ cat setup.cfg + [metadata] + name = CLVault + version = 0.1 + author = Tarek Ziade + author_email = tarek at ziade.org + description = Command-line utility to store and retrieve passwords + home_page = http://bitbucket.org/tarek/clvault + + classifier = Development Status :: 3 - Alpha + License :: OSI Approved :: GNU General Public License (GPL) + + [files] + packages = clvault + + +Our project will depend on the *keyring* project. Let's add it in the +[metadata] section:: + + [metadata] + ... + requires_dist = + keyring + + +Running commands +---------------- + +You can run useful commands on your project once the setup.cfg file is ready: + +- sdist: creates a source distribution +- register: register your project to PyPI +- upload: upload the distribution to PyPI +- install_dist: install it + +All commands are run using the run script:: + + $ pysetup run install_dist + $ pysetup run sdist + $ pysetup run upload + +If you want to push a source distribution of your project to PyPI, do:: + + $ pysetup run sdist register upload + + +Installing the project +---------------------- + +The project can be installed by manually running the packaging install command:: + + $ pysetup run install_dist diff --git a/Doc/packaging/uploading.rst b/Doc/packaging/uploading.rst new file mode 100644 --- /dev/null +++ b/Doc/packaging/uploading.rst @@ -0,0 +1,80 @@ +.. _packaging-package-upload: + +*************************************** +Uploading Packages to the Package Index +*************************************** + +The Python Package Index (PyPI) not only stores the package info, but also the +package data if the author of the package wishes to. The packaging command +:command:`upload` pushes the distribution files to PyPI. + +The command is invoked immediately after building one or more distribution +files. For example, the command :: + + python setup.py sdist bdist_wininst upload + +will cause the source distribution and the Windows installer to be uploaded to +PyPI. Note that these will be uploaded even if they are built using an earlier +invocation of :file:`setup.py`, but that only distributions named on the command +line for the invocation including the :command:`upload` command are uploaded. + +The :command:`upload` command uses the username, password, and repository URL +from the :file:`$HOME/.pypirc` file (see section :ref:`packaging-pypirc` for more on this +file). If a :command:`register` command was previously called in the same +command, and if the password was entered in the prompt, :command:`upload` will +reuse the entered password. This is useful if you do not want to store a clear +text password in the :file:`$HOME/.pypirc` file. + +You can specify another PyPI server with the :option:`--repository=*url*` +option:: + + python setup.py sdist bdist_wininst upload -r http://example.com/pypi + +See section :ref:`packaging-pypirc` for more on defining several servers. + +You can use the :option:`--sign` option to tell :command:`upload` to sign each +uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must +be available for execution on the system :envvar:`PATH`. You can also specify +which key to use for signing using the :option:`--identity=*name*` option. + +Other :command:`upload` options include :option:`--repository=` or +:option:`--repository=
` where *url* is the url of the server and +*section* the name of the section in :file:`$HOME/.pypirc`, and +:option:`--show-response` (which displays the full response text from the PyPI +server for help in debugging upload problems). + +PyPI package display +==================== + +The ``description`` field plays a special role at PyPI. It is used by +the server to display a home page for the registered package. + +If you use the `reStructuredText `_ +syntax for this field, PyPI will parse it and display an HTML output for +the package home page. + +The ``description`` field can be filled from a text file located in the +project:: + + from packaging.core import setup + + fp = open('README.txt') + try: + description = fp.read() + finally: + fp.close() + + setup(name='Packaging', + description=description) + +In that case, :file:`README.txt` is a regular reStructuredText text file located +in the root of the package besides :file:`setup.py`. + +To prevent registering broken reStructuredText content, you can use the +:program:`rst2html` program that is provided by the :mod:`docutils` package +and check the ``description`` from the command line:: + + $ python setup.py --description | rst2html.py > output.html + +:mod:`docutils` will display a warning if there's something wrong with your +syntax. diff --git a/Doc/tools/sphinxext/indexcontent.html b/Doc/tools/sphinxext/indexcontent.html --- a/Doc/tools/sphinxext/indexcontent.html +++ b/Doc/tools/sphinxext/indexcontent.html @@ -20,10 +20,10 @@ tutorial for C/C++ programmers

- - + +

' + html.bigsection( - 'Built-in Modules', '#ffffff', '#ee77aa', contents)] - - seen = {} - for dir in sys.path: - indices.append(html.index(dir, seen)) - contents = heading + ' '.join(indices) + '''

- -pydoc by Ka-Ping Yee <ping at lfw.org>''' - self.send_document('Index of Modules', contents) - - def log_message(self, *args): pass - - class DocServer(http.server.HTTPServer): - def __init__(self, port, callback): - host = 'localhost' - self.address = (host, port) - self.url = 'http://%s:%d/' % (host, port) - self.callback = callback - self.base.__init__(self, self.address, self.handler) - - def serve_until_quit(self): - import select - self.quit = False - while not self.quit: - rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) - if rd: self.handle_request() - self.server_close() - - def server_activate(self): - self.base.server_activate(self) - if self.callback: self.callback(self) - - DocServer.base = http.server.HTTPServer - DocServer.handler = DocHandler - DocHandler.MessageClass = email.message.Message - try: - try: - DocServer(port, callback).serve_until_quit() - except (KeyboardInterrupt, select.error): - pass - finally: - if completer: completer() - -# ----------------------------------------------------- graphical interface - -def gui(): - """Graphical interface (starts Web server and pops up a control window).""" - - msg = ('the pydoc.gui() function and "pydoc -g" option are deprecated\n', - 'use "pydoc.browse() function and "pydoc -b" option instead.') - warnings.warn(msg, DeprecationWarning, stacklevel=2) - - class GUI: - def __init__(self, window, port=7464): - self.window = window - self.server = None - self.scanner = None - - import tkinter - self.server_frm = tkinter.Frame(window) - self.title_lbl = tkinter.Label(self.server_frm, - text='Starting server...\n ') - self.open_btn = tkinter.Button(self.server_frm, - text='open browser', command=self.open, state='disabled') - self.quit_btn = tkinter.Button(self.server_frm, - text='quit serving', command=self.quit, state='disabled') - - self.search_frm = tkinter.Frame(window) - self.search_lbl = tkinter.Label(self.search_frm, text='Search for') - self.search_ent = tkinter.Entry(self.search_frm) - self.search_ent.bind('', self.search) - self.stop_btn = tkinter.Button(self.search_frm, - text='stop', pady=0, command=self.stop, state='disabled') - if sys.platform == 'win32': - # Trying to hide and show this button crashes under Windows. - self.stop_btn.pack(side='right') - - self.window.title('pydoc') - self.window.protocol('WM_DELETE_WINDOW', self.quit) - self.title_lbl.pack(side='top', fill='x') - self.open_btn.pack(side='left', fill='x', expand=1) - self.quit_btn.pack(side='right', fill='x', expand=1) - self.server_frm.pack(side='top', fill='x') - - self.search_lbl.pack(side='left') - self.search_ent.pack(side='right', fill='x', expand=1) - self.search_frm.pack(side='top', fill='x') - self.search_ent.focus_set() - - font = ('helvetica', sys.platform == 'win32' and 8 or 10) - self.result_lst = tkinter.Listbox(window, font=font, height=6) - self.result_lst.bind('', self.select) - self.result_lst.bind('', self.goto) - self.result_scr = tkinter.Scrollbar(window, - orient='vertical', command=self.result_lst.yview) - self.result_lst.config(yscrollcommand=self.result_scr.set) - - self.result_frm = tkinter.Frame(window) - self.goto_btn = tkinter.Button(self.result_frm, - text='go to selected', command=self.goto) - self.hide_btn = tkinter.Button(self.result_frm, - text='hide results', command=self.hide) - self.goto_btn.pack(side='left', fill='x', expand=1) - self.hide_btn.pack(side='right', fill='x', expand=1) - - self.window.update() - self.minwidth = self.window.winfo_width() - self.minheight = self.window.winfo_height() - self.bigminheight = (self.server_frm.winfo_reqheight() + - self.search_frm.winfo_reqheight() + - self.result_lst.winfo_reqheight() + - self.result_frm.winfo_reqheight()) - self.bigwidth, self.bigheight = self.minwidth, self.bigminheight - self.expanded = 0 - self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) - self.window.wm_minsize(self.minwidth, self.minheight) - self.window.tk.willdispatch() - - import threading - threading.Thread( - target=serve, args=(port, self.ready, self.quit)).start() - - def ready(self, server): - self.server = server - self.title_lbl.config( - text='Python documentation server at\n' + server.url) - self.open_btn.config(state='normal') - self.quit_btn.config(state='normal') - - def open(self, event=None, url=None): - url = url or self.server.url - import webbrowser - webbrowser.open(url) - - def quit(self, event=None): - if self.server: - self.server.quit = 1 - self.window.quit() - - def search(self, event=None): - key = self.search_ent.get() - self.stop_btn.pack(side='right') - self.stop_btn.config(state='normal') - self.search_lbl.config(text='Searching for "%s"...' % key) - self.search_ent.forget() - self.search_lbl.pack(side='left') - self.result_lst.delete(0, 'end') - self.goto_btn.config(state='disabled') - self.expand() - - import threading - if self.scanner: - self.scanner.quit = 1 - self.scanner = ModuleScanner() - threading.Thread(target=self.scanner.run, - args=(self.update, key, self.done)).start() - - def update(self, path, modname, desc): - if modname[-9:] == '.__init__': - modname = modname[:-9] + ' (package)' - self.result_lst.insert('end', - modname + ' - ' + (desc or '(no description)')) - - def stop(self, event=None): - if self.scanner: - self.scanner.quit = 1 - self.scanner = None - - def done(self): - self.scanner = None - self.search_lbl.config(text='Search for') - self.search_lbl.pack(side='left') - self.search_ent.pack(side='right', fill='x', expand=1) - if sys.platform != 'win32': self.stop_btn.forget() - self.stop_btn.config(state='disabled') - - def select(self, event=None): - self.goto_btn.config(state='normal') - - def goto(self, event=None): - selection = self.result_lst.curselection() - if selection: - modname = self.result_lst.get(selection[0]).split()[0] - self.open(url=self.server.url + modname + '.html') - - def collapse(self): - if not self.expanded: return - self.result_frm.forget() - self.result_scr.forget() - self.result_lst.forget() - self.bigwidth = self.window.winfo_width() - self.bigheight = self.window.winfo_height() - self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) - self.window.wm_minsize(self.minwidth, self.minheight) - self.expanded = 0 - - def expand(self): - if self.expanded: return - self.result_frm.pack(side='bottom', fill='x') - self.result_scr.pack(side='right', fill='y') - self.result_lst.pack(side='top', fill='both', expand=1) - self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight)) - self.window.wm_minsize(self.minwidth, self.bigminheight) - self.expanded = 1 - - def hide(self, event=None): - self.stop() - self.collapse() - - import tkinter - try: - root = tkinter.Tk() - # Tk will crash if pythonw.exe has an XP .manifest - # file and the root has is not destroyed explicitly. - # If the problem is ever fixed in Tk, the explicit - # destroy can go. - try: - gui = GUI(root) - root.mainloop() - finally: - root.destroy() - except KeyboardInterrupt: - pass - - # --------------------------------------- enhanced Web browser interface def _start_server(urlhandler, port): @@ -2778,15 +2506,12 @@ sys.path.insert(0, '.') try: - opts, args = getopt.getopt(sys.argv[1:], 'bgk:p:w') + opts, args = getopt.getopt(sys.argv[1:], 'bk:p:w') writing = False start_server = False open_browser = False port = None for opt, val in opts: - if opt == '-g': - gui() - return if opt == '-b': start_server = True open_browser = True @@ -2847,9 +2572,6 @@ to interactively browse documentation. The -p option can be used with the -b option to explicitly specify the server port. -{cmd} -g - Deprecated. - {cmd} -w ... Write out the HTML documentation for a module to a file in the current directory. If contains a '{sep}', it is treated as a filename; if diff --git a/Lib/reprlib.py b/Lib/reprlib.py --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -5,7 +5,7 @@ import builtins from itertools import islice try: - from _thread import get_ident + from threading import get_ident except ImportError: from _dummy_thread import get_ident diff --git a/Lib/socketserver.py b/Lib/socketserver.py --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -82,7 +82,7 @@ data is stored externally (e.g. in the file system), a synchronous class will essentially render the service "deaf" while one request is being handled -- which may be for a very long time if a client is slow -to reqd all the data it has requested. Here a threading or forking +to recv all the data it has requested. Here a threading or forking server is appropriate. In some cases, it may be appropriate to process part of a request @@ -170,6 +170,7 @@ - process_request(request, client_address) - shutdown_request(request) - close_request(request) + - service_actions() - handle_error() Methods for derived classes: @@ -225,6 +226,8 @@ r, w, e = select.select([self], [], [], poll_interval) if self in r: self._handle_request_noblock() + + self.service_actions() finally: self.__shutdown_request = False self.__is_shut_down.set() @@ -239,6 +242,14 @@ self.__shutdown_request = True self.__is_shut_down.wait() + def service_actions(self): + """Called by the serve_forever() loop. + + May be overridden by a subclass / Mixin to implement any code that + needs to be run during the loop. + """ + pass + # The distinction between handling, getting, processing and # finishing a request is fairly arbitrary. Remember: # @@ -539,9 +550,15 @@ """ self.collect_children() + def service_actions(self): + """Collect the zombie child processes regularly in the ForkingMixin. + + service_actions is called in the BaseServer's serve_forver loop. + """ + self.collect_children() + def process_request(self, request, client_address): """Fork a new subprocess to process the request.""" - self.collect_children() pid = os.fork() if pid: # Parent process diff --git a/Lib/ssl.py b/Lib/ssl.py --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -63,7 +63,7 @@ from _ssl import _SSLContext, SSLError from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED from _ssl import OP_ALL, OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_TLSv1 -from _ssl import RAND_status, RAND_egd, RAND_add +from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes from _ssl import ( SSL_ERROR_ZERO_RETURN, SSL_ERROR_WANT_READ, diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -397,39 +397,14 @@ else: import select _has_poll = hasattr(select, 'poll') - import fcntl - import pickle - - try: - import _posixsubprocess - except ImportError: - _posixsubprocess = None - warnings.warn("The _posixsubprocess module is not being used. " - "Child process reliability may suffer if your " - "program uses threads.", RuntimeWarning) + import _posixsubprocess + _create_pipe = _posixsubprocess.cloexec_pipe # When select or poll has indicated that the file is writable, # we can write up to _PIPE_BUF bytes without risk of blocking. # POSIX defines PIPE_BUF as >= 512. _PIPE_BUF = getattr(select, 'PIPE_BUF', 512) - _FD_CLOEXEC = getattr(fcntl, 'FD_CLOEXEC', 1) - - def _set_cloexec(fd, cloexec): - old = fcntl.fcntl(fd, fcntl.F_GETFD) - if cloexec: - fcntl.fcntl(fd, fcntl.F_SETFD, old | _FD_CLOEXEC) - else: - fcntl.fcntl(fd, fcntl.F_SETFD, old & ~_FD_CLOEXEC) - - if _posixsubprocess: - _create_pipe = _posixsubprocess.cloexec_pipe - else: - def _create_pipe(): - fds = os.pipe() - _set_cloexec(fds[0], True) - _set_cloexec(fds[1], True) - return fds __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", "getoutput", "check_output", "CalledProcessError", "DEVNULL"] @@ -800,7 +775,10 @@ self.wait() def __del__(self, _maxsize=sys.maxsize, _active=_active): - if not self._child_created: + # If __init__ hasn't had a chance to execute (e.g. if it + # was passed an undeclared keyword argument), we don't + # have a _child_created attribute at all. + if not getattr(self, '_child_created', False): # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. @@ -1267,140 +1245,33 @@ errpipe_read, errpipe_write = _create_pipe() try: try: + # We must avoid complex work that could involve + # malloc or free in the child process to avoid + # potential deadlocks, thus we do all this here. + # and pass it to fork_exec() - if _posixsubprocess: - # We must avoid complex work that could involve - # malloc or free in the child process to avoid - # potential deadlocks, thus we do all this here. - # and pass it to fork_exec() - - if env: - env_list = [os.fsencode(k) + b'=' + os.fsencode(v) - for k, v in env.items()] - else: - env_list = None # Use execv instead of execve. - executable = os.fsencode(executable) - if os.path.dirname(executable): - executable_list = (executable,) - else: - # This matches the behavior of os._execvpe(). - executable_list = tuple( - os.path.join(os.fsencode(dir), executable) - for dir in os.get_exec_path(env)) - fds_to_keep = set(pass_fds) - fds_to_keep.add(errpipe_write) - self.pid = _posixsubprocess.fork_exec( - args, executable_list, - close_fds, sorted(fds_to_keep), cwd, env_list, - p2cread, p2cwrite, c2pread, c2pwrite, - errread, errwrite, - errpipe_read, errpipe_write, - restore_signals, start_new_session, preexec_fn) + if env: + env_list = [os.fsencode(k) + b'=' + os.fsencode(v) + for k, v in env.items()] else: - # Pure Python implementation: It is not thread safe. - # This implementation may deadlock in the child if your - # parent process has any other threads running. - - gc_was_enabled = gc.isenabled() - # Disable gc to avoid bug where gc -> file_dealloc -> - # write to stderr -> hang. See issue1336 - gc.disable() - try: - self.pid = os.fork() - except: - if gc_was_enabled: - gc.enable() - raise - self._child_created = True - if self.pid == 0: - # Child - try: - # Close parent's pipe ends - if p2cwrite != -1: - os.close(p2cwrite) - if c2pread != -1: - os.close(c2pread) - if errread != -1: - os.close(errread) - os.close(errpipe_read) - - # Dup fds for child - def _dup2(a, b): - # dup2() removes the CLOEXEC flag but - # we must do it ourselves if dup2() - # would be a no-op (issue #10806). - if a == b: - _set_cloexec(a, False) - elif a != -1: - os.dup2(a, b) - _dup2(p2cread, 0) - _dup2(c2pwrite, 1) - _dup2(errwrite, 2) - - # Close pipe fds. Make sure we don't close the - # same fd more than once, or standard fds. - closed = set() - for fd in [p2cread, c2pwrite, errwrite]: - if fd > 2 and fd not in closed: - os.close(fd) - closed.add(fd) - - # Close all other fds, if asked for - if close_fds: - fds_to_keep = set(pass_fds) - fds_to_keep.add(errpipe_write) - self._close_fds(fds_to_keep) - - - if cwd is not None: - os.chdir(cwd) - - # This is a copy of Python/pythonrun.c - # _Py_RestoreSignals(). If that were exposed - # as a sys._py_restoresignals func it would be - # better.. but this pure python implementation - # isn't likely to be used much anymore. - if restore_signals: - signals = ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ') - for sig in signals: - if hasattr(signal, sig): - signal.signal(getattr(signal, sig), - signal.SIG_DFL) - - if start_new_session and hasattr(os, 'setsid'): - os.setsid() - - if preexec_fn: - preexec_fn() - - if env is None: - os.execvp(executable, args) - else: - os.execvpe(executable, args, env) - - except: - try: - exc_type, exc_value = sys.exc_info()[:2] - if isinstance(exc_value, OSError): - errno_num = exc_value.errno - else: - errno_num = 0 - message = '%s:%x:%s' % (exc_type.__name__, - errno_num, exc_value) - message = message.encode(errors="surrogatepass") - os.write(errpipe_write, message) - except Exception: - # We MUST not allow anything odd happening - # above to prevent us from exiting below. - pass - - # This exitcode won't be reported to applications - # so it really doesn't matter what we return. - os._exit(255) - - # Parent - if gc_was_enabled: - gc.enable() + env_list = None # Use execv instead of execve. + executable = os.fsencode(executable) + if os.path.dirname(executable): + executable_list = (executable,) + else: + # This matches the behavior of os._execvpe(). + executable_list = tuple( + os.path.join(os.fsencode(dir), executable) + for dir in os.get_exec_path(env)) + fds_to_keep = set(pass_fds) + fds_to_keep.add(errpipe_write) + self.pid = _posixsubprocess.fork_exec( + args, executable_list, + close_fds, sorted(fds_to_keep), cwd, env_list, + p2cread, p2cwrite, c2pread, c2pwrite, + errread, errwrite, + errpipe_read, errpipe_write, + restore_signals, start_new_session, preexec_fn) finally: # be sure the FD is closed no matter what os.close(errpipe_write) diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -287,14 +287,16 @@ variables.remove(name) if name.startswith('PY_') \ - and name[3:] in renamed_variables: + and name[3:] in renamed_variables: name = name[3:] if name not in done: done[name] = value else: - # bogus variable reference; just drop it since we can't deal + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value variables.remove(name) # strip spurious spaces @@ -656,11 +658,10 @@ # to. This makes the compatibility story a bit more sane because the # machine is going to compile and link as if it were # MACOSX_DEPLOYMENT_TARGET. - # cfgvars = get_config_vars() macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') - if 1: + if True: # Always calculate the release of the running machine, # needed to determine if we can build fat binaries or not. @@ -755,7 +756,7 @@ print('Platform: "%s"' % get_platform()) print('Python version: "%s"' % get_python_version()) print('Current installation scheme: "%s"' % _get_default_scheme()) - print('') + print() _print_dict('Paths', get_paths()) print() _print_dict('Variables', get_config_vars()) diff --git a/Lib/tarfile.py b/Lib/tarfile.py --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -29,8 +29,6 @@ """Read from and write to tar format archives. """ -__version__ = "$Revision$" - version = "0.9.0" __author__ = "Lars Gust\u00e4bel (lars at gustaebel.de)" __date__ = "$Date$" diff --git a/Lib/test/cjkencodings/hz-utf8.txt b/Lib/test/cjkencodings/hz-utf8.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/hz-utf8.txt @@ -0,0 +1,2 @@ +This sentence is in ASCII. +The next sentence is in GB.??????????Bye. diff --git a/Lib/test/cjkencodings/hz.txt b/Lib/test/cjkencodings/hz.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/hz.txt @@ -0,0 +1,2 @@ +This sentence is in ASCII. +The next sentence is in GB.~{<:Ky2;S{#,NpJ)l6HK!#~}Bye. diff --git a/Lib/test/cjkencodings/iso2022_jp-utf8.txt b/Lib/test/cjkencodings/iso2022_jp-utf8.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_jp-utf8.txt @@ -0,0 +1,7 @@ +Python ?????1990 ?????????????? +???? Guido van Rossum ???????????????ABC???????????????ABC ??????????????????????? +?????Guido ?????????????????????????? BBS ?????????????? ???????????? Guido ???????Python????????? +????????????? Python ?????????????????????????????????????? +????????????????????????????????????????????????????????Python ???????????????????????????? +?????????????????????????????????????????? Python ???????? + diff --git a/Lib/test/cjkencodings/iso2022_jp.txt b/Lib/test/cjkencodings/iso2022_jp.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_jp.txt @@ -0,0 +1,7 @@ +Python $B$N3+H/$O!"(B1990 $BG/$4$m$+$i3+;O$5$l$F$$$^$9!#(B +$B3+H/e$NL\E*$K$O$"$^$jE,$7$F$$$^$;$s$G$7$?!#(B +$B$3$N$?$a!"(BGuido $B$O$h$j$E$1$^$7$?!#(B +$B$3$N$h$&$JGX7J$+$i at 8$^$l$?(B Python $B$N8 at 8l@_7W$O!"!V%7%s%W%k!W$G!V=,F@$,MF0W!W$H$$$&L\I8$K=EE@$,CV$+$l$F$$$^$9!#(B +$BB?$/$N%9%/%j%W%H7O8 at 8l$G$O%f!<%6$NL\@h$NMxJX at -$rM%@h$7$F?'!9$J5!G=$r8 at 8lMWAG$H$7$Fl9g$,B?$$$N$G$9$,!"(BPython $B$G$O$=$&$$$C$?>.:Y9)$,DI2C$5$l$k$3$H$O$"$^$j$"$j$^$;$s!#(B +$B8 at 8l<+BN$N5!G=$O:G>.8B$K2!$5$(!"I,MW$J5!G=$O3HD%%b%8%e!<%k$H$7$FDI2C$9$k!"$H$$$&$N$,(B Python $B$N%]%j%7!<$G$9!#(B + diff --git a/Lib/test/cjkencodings/iso2022_kr-utf8.txt b/Lib/test/cjkencodings/iso2022_kr-utf8.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_kr-utf8.txt @@ -0,0 +1,7 @@ +? ???(Python)? ??? ??, ??? ????? ?????. ???? +???? ??? ??? ??? ????? ???? ?????????? +?????. ???? ??(??)? ??? ?? ???, ??? ????? +??? ???? ????? ?? ????? ???? ?????? ?? +?????? ??? ? ? ?? ???? ??? ??????. + +????: ??? ?~ ?! ??? ???. ??? ?. diff --git a/Lib/test/cjkencodings/iso2022_kr.txt b/Lib/test/cjkencodings/iso2022_kr.txt new file mode 100644 --- /dev/null +++ b/Lib/test/cjkencodings/iso2022_kr.txt @@ -0,0 +1,7 @@ +$)C!] FD at L=c(Python)@: 9h?l1b =10m, 0-7BGQ GA7N1W7!9V >p>n at T4O4Y. FD at L=c@: +H?@2@{@N 0mF(iPd:)GQ 9.9}0z 5?@{ E8 at LGN, 1W8.0m @NEMGA8.FC +H/0f@: FD at L=c@; =:E)83FC0z ?)7/ :P>_?!<-?M 4k:N:P at G GC7'F{?!<- at G :|8% +>VGC8.DI at Lp>n7N 885i>nA]4O4Y. + +!YC90!3!: 3/>F6s >1~ E-! 1]>x at L @|4O4Y. 1W710E 4Y. diff --git a/Lib/test/decimaltestdata/extra.decTest b/Lib/test/decimaltestdata/extra.decTest --- a/Lib/test/decimaltestdata/extra.decTest +++ b/Lib/test/decimaltestdata/extra.decTest @@ -222,12 +222,25 @@ extr1701 power 100.0 -557.71e-742888888 -> 1.000000000000000 Inexact Rounded extr1702 power 10 1e-100 -> 1.000000000000000 Inexact Rounded +-- Another one (see issue #12080). Thanks again to Stefan Krah. +extr1703 power 4 -1.2e-999999999 -> 1.000000000000000 Inexact Rounded + -- A couple of interesting exact cases for power. Note that the specification -- requires these to be reported as Inexact. extr1710 power 1e375 56e-3 -> 1.000000000000000E+21 Inexact Rounded extr1711 power 10000 0.75 -> 1000.000000000000 Inexact Rounded extr1712 power 1e-24 0.875 -> 1.000000000000000E-21 Inexact Rounded +-- Some more exact cases, exercising power with negative second argument. +extr1720 power 400 -0.5 -> 0.05000000000000000 Inexact Rounded +extr1721 power 4096 -0.75 -> 0.001953125000000000 Inexact Rounded +extr1722 power 625e4 -0.25 -> 0.02000000000000000 Inexact Rounded + +-- Nonexact cases, to exercise some of the early exit conditions from +-- _power_exact. +extr1730 power 2048 -0.75 -> 0.003284751622084822 Inexact Rounded + + -- Tests for the is_* boolean operations precision: 9 maxExponent: 999 diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -4,7 +4,7 @@ import sys import time -from _thread import start_new_thread, get_ident, TIMEOUT_MAX +from _thread import start_new_thread, TIMEOUT_MAX import threading import unittest @@ -31,7 +31,7 @@ self.finished = [] self._can_exit = not wait_before_exit def task(): - tid = get_ident() + tid = threading.get_ident() self.started.append(tid) try: f() diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -22,8 +22,7 @@ -h/--help -- print this text and exit --timeout TIMEOUT -- dump the traceback and exit if a test takes more - than TIMEOUT seconds (default: 30 minutes); disable - the timeout if TIMEOUT is zero + than TIMEOUT seconds --wait -- wait for user input, e.g., allow a debugger to be attached Verbosity @@ -269,11 +268,6 @@ # Display the Python traceback fatal errors (e.g. segfault) faulthandler.enable(all_threads=True) - if hasattr(faulthandler, 'dump_tracebacks_later'): - timeout = 60*60 - else: - timeout = None - replace_stdout() support.record_original_stdout(sys.stdout) @@ -295,6 +289,7 @@ use_resources = [] debug = False start = None + timeout = None for o, a in opts: if o in ('-h', '--help'): print(__doc__) @@ -420,10 +415,13 @@ testdir = os.path.join(support.SAVEDCWD, a) elif o == '--timeout': if not hasattr(faulthandler, 'dump_tracebacks_later'): - print("--timeout option requires " + print("The timeout option requires " "faulthandler.dump_tracebacks_later", file=sys.stderr) sys.exit(1) timeout = float(a) + if timeout <= 0: + print("The timeout must be greater than 0", file=sys.stderr) + sys.exit(1) elif o == '--wait': input("Press any key to continue...") else: @@ -630,9 +628,12 @@ if test is None: finished += 1 continue + accumulate_result(test, result) if not quiet: - print("[{1:{0}}{2}] {3}".format( - test_count_width, test_index, test_count, test)) + fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}" + print(fmt.format( + test_count_width, test_index, test_count, + len(bad), test)) if stdout: print(stdout) if stderr: @@ -642,7 +643,6 @@ raise KeyboardInterrupt # What else? if result[0] == CHILD_ERROR: raise Exception("Child error on {}: {}".format(test, result[1])) - accumulate_result(test, result) test_index += 1 except KeyboardInterrupt: interrupted = True @@ -652,8 +652,9 @@ else: for test_index, test in enumerate(tests, 1): if not quiet: - print("[{1:{0}}{2}] {3}".format( - test_count_width, test_index, test_count, test)) + fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}" + print(fmt.format( + test_count_width, test_index, test_count, len(bad), test)) sys.stdout.flush() if trace: # If we're tracing code coverage, then we don't exit with status @@ -791,17 +792,14 @@ def replace_stdout(): """Set stdout encoder error handler to backslashreplace (as stderr error handler) to avoid UnicodeEncodeError when printing a traceback""" - if os.name == "nt": - # Replace sys.stdout breaks the stdout newlines on Windows: issue #8533 - return - import atexit stdout = sys.stdout sys.stdout = open(stdout.fileno(), 'w', encoding=stdout.encoding, errors="backslashreplace", - closefd=False) + closefd=False, + newline='\n') def restore_stdout(): sys.stdout.close() @@ -835,7 +833,7 @@ support.verbose = verbose # Tell tests to be moderately quiet if use_resources is not None: support.use_resources = use_resources - use_timeout = (timeout is not None and timeout > 0) + use_timeout = (timeout is not None) if use_timeout: faulthandler.dump_tracebacks_later(timeout, exit=True) try: @@ -1023,10 +1021,6 @@ def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False): support.unload(test) - if verbose: - capture_stdout = None - else: - capture_stdout = io.StringIO() test_time = 0.0 refleak = False # True if the test leaked references. diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -37,7 +37,8 @@ "Error", "TestFailed", "ResourceDenied", "import_module", "verbose", "use_resources", "max_memuse", "record_original_stdout", "get_original_stdout", "unload", "unlink", "rmtree", "forget", - "is_resource_enabled", "requires", "find_unused_port", "bind_port", + "is_resource_enabled", "requires", "requires_linux_version", + "requires_mac_ver", "find_unused_port", "bind_port", "IPV6_ENABLED", "is_jython", "TESTFN", "HOST", "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error", "open_urlresource", "check_warnings", "CleanImport", "EnvironmentVarGuard", "TransientResource", @@ -48,7 +49,7 @@ "threading_cleanup", "reap_children", "cpython_only", "check_impl_detail", "get_attribute", "swap_item", "swap_attr", "requires_IEEE_754", "TestHandler", "Matcher", "can_symlink", "skip_unless_symlink", - "import_fresh_module", "requires_zlib" + "import_fresh_module", "requires_zlib", "PIPE_MAX_SIZE" ] class Error(Exception): @@ -291,6 +292,61 @@ msg = "Use of the `%s' resource not enabled" % resource raise ResourceDenied(msg) +def requires_linux_version(*min_version): + """Decorator raising SkipTest if the OS is Linux and the kernel version is + less than min_version. + + For example, @requires_linux_version(2, 6, 35) raises SkipTest if the Linux + kernel version is less than 2.6.35. + """ + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kw): + if sys.platform.startswith('linux'): + version_txt = platform.release().split('-', 1)[0] + try: + version = tuple(map(int, version_txt.split('.'))) + except ValueError: + pass + else: + if version < min_version: + min_version_txt = '.'.join(map(str, min_version)) + raise unittest.SkipTest( + "Linux kernel %s or higher required, not %s" + % (min_version_txt, version_txt)) + return func(*args, **kw) + wrapper.min_version = min_version + return wrapper + return decorator + +def requires_mac_ver(*min_version): + """Decorator raising SkipTest if the OS is Mac OS X and the OS X + version if less than min_version. + + For example, @requires_mac_ver(10, 5) raises SkipTest if the OS X version + is lesser than 10.5. + """ + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kw): + if sys.platform == 'darwin': + version_txt = platform.mac_ver()[0] + try: + version = tuple(map(int, version_txt.split('.'))) + except ValueError: + pass + else: + if version < min_version: + min_version_txt = '.'.join(map(str, min_version)) + raise unittest.SkipTest( + "Mac OS X %s or higher required, not %s" + % (min_version_txt, version_txt)) + return func(*args, **kw) + wrapper.min_version = min_version + return wrapper + return decorator + + HOST = 'localhost' def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): @@ -401,6 +457,13 @@ IPV6_ENABLED = _is_ipv6_enabled() + +# A constant likely larger than the underlying OS pipe buffer size. +# Windows limit seems to be around 512B, and most Unix kernels have a 64K pipe +# buffer size: take 1M to be sure. +PIPE_MAX_SIZE = 1024 * 1024 + + # decorator for skipping tests on non-IEEE 754 platforms requires_IEEE_754 = unittest.skipUnless( float.__getformat__("double").startswith("IEEE"), diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py --- a/Lib/test/test_abstract_numbers.py +++ b/Lib/test/test_abstract_numbers.py @@ -14,6 +14,7 @@ self.assertEqual(7, int(7).real) self.assertEqual(0, int(7).imag) self.assertEqual(7, int(7).conjugate()) + self.assertEqual(-7, int(-7).conjugate()) self.assertEqual(7, int(7).numerator) self.assertEqual(1, int(7).denominator) @@ -24,6 +25,7 @@ self.assertEqual(7.3, float(7.3).real) self.assertEqual(0, float(7.3).imag) self.assertEqual(7.3, float(7.3).conjugate()) + self.assertEqual(-7.3, float(-7.3).conjugate()) def test_complex(self): self.assertFalse(issubclass(complex, Real)) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -38,6 +38,9 @@ "while v:pass", # If "if v:pass", + # With + "with x as y: pass", + "with x as y, z as q: pass", # Raise "raise Exception('string')", # TryExcept @@ -341,9 +344,11 @@ ('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]), ('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]), ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]), +('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]), +('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]), ('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]), -('Module', [('TryExcept', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [])]), -('Module', [('TryFinally', (1, 0), [('Pass', (2, 2))], [('Pass', (4, 2))])]), +('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]), +('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), ('Module', [('Import', (1, 0), [('alias', 'sys', None)])]), ('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]), diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -330,6 +330,16 @@ except (Exception) as e_len: self.assertEqual(str(e_bool), str(e_len)) + def test_real_and_imag(self): + self.assertEqual(True.real, 1) + self.assertEqual(True.imag, 0) + self.assertIs(type(True.real), int) + self.assertIs(type(True.imag), int) + self.assertEqual(False.real, 0) + self.assertEqual(False.imag, 0) + self.assertIs(type(False.real), int) + self.assertIs(type(False.imag), int) + def test_main(): support.run_unittest(BoolTest) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -385,6 +385,8 @@ except: self.assertEqual(len(dir(sys.exc_info()[2])), 4) + # test that object has a __dir__() + self.assertEqual(sorted([].__dir__()), dir([])) def test_divmod(self): self.assertEqual(divmod(12, 7), (1, 5)) diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -47,7 +47,6 @@ ] TEXT = b''.join(TEXT_LINES) DATA = b'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' - DATA_CRLF = b'BZh91AY&SY\xaez\xbbN\x00\x01H\xdf\x80\x00\x12@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe0@\x01\xbc\xc6`\x86*\x8d=M\xa9\x9a\x86\xd0L@\x0fI\xa6!\xa1\x13\xc8\x88jdi\x8d@\x03@\x1a\x1a\x0c\x0c\x83 \x00\xc4h2\x19\x01\x82D\x84e\t\xe8\x99\x89\x19\x1ah\x00\r\x1a\x11\xaf\x9b\x0fG\xf5(\x1b\x1f?\t\x12\xcf\xb5\xfc\x95E\x00ps\x89\x12^\xa4\xdd\xa2&\x05(\x87\x04\x98\x89u\xe40%\xb6\x19\'\x8c\xc4\x89\xca\x07\x0e\x1b!\x91UIFU%C\x994!DI\xd2\xfa\xf0\xf1N8W\xde\x13A\xf5\x9cr%?\x9f3;I45A\xd1\x8bT\xb1\xa4\xc7\x8d\x1a\\"\xad\xa1\xabyBg\x15\xb9l\x88\x88\x91k"\x94\xa4\xd4\x89\xae*\xa6\x0b\x10\x0c\xd6\xd4m\xe86\xec\xb5j\x8a\x86j\';\xca.\x01I\xf2\xaaJ\xe8\x88\x8cU+t3\xfb\x0c\n\xa33\x13r2\r\x16\xe0\xb3(\xbf\x1d\x83r\xe7M\xf0D\x1365\xd8\x88\xd3\xa4\x92\xcb2\x06\x04\\\xc1\xb0\xea//\xbek&\xd8\xe6+t\xe5\xa1\x13\xada\x16\xder5"w]\xa2i\xb7[\x97R \xe2IT\xcd;Z\x04dk4\xad\x8a\t\xd3\x81z\x10\xf1:^`\xab\x1f\xc5\xdc\x91N\x14$+\x9e\xae\xd3\x80' if has_cmdline_bunzip2: def decompress(self, data): @@ -78,50 +77,69 @@ if os.path.isfile(self.filename): os.unlink(self.filename) - def getData(self, crlf=False): - if crlf: - return self.DATA_CRLF - else: - return self.DATA - - def createTempFile(self, crlf=False): + def createTempFile(self, streams=1): with open(self.filename, "wb") as f: - f.write(self.getData(crlf)) + f.write(self.DATA * streams) def testRead(self): - # "Test BZ2File.read()" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertRaises(TypeError, bz2f.read, None) self.assertEqual(bz2f.read(), self.TEXT) + def testReadMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + self.assertRaises(TypeError, bz2f.read, None) + self.assertEqual(bz2f.read(), self.TEXT * 5) + + def testReadMonkeyMultiStream(self): + # Test BZ2File.read() on a multi-stream archive where a stream + # boundary coincides with the end of the raw read buffer. + buffer_size = bz2._BUFFER_SIZE + bz2._BUFFER_SIZE = len(self.DATA) + try: + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + self.assertRaises(TypeError, bz2f.read, None) + self.assertEqual(bz2f.read(), self.TEXT * 5) + finally: + bz2._BUFFER_SIZE = buffer_size + def testRead0(self): - # "Test BBZ2File.read(0)" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertRaises(TypeError, bz2f.read, None) self.assertEqual(bz2f.read(0), b"") def testReadChunk10(self): - # "Test BZ2File.read() in chunks of 10 bytes" self.createTempFile() with BZ2File(self.filename) as bz2f: text = b'' - while 1: + while True: str = bz2f.read(10) if not str: break text += str self.assertEqual(text, self.TEXT) + def testReadChunk10MultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + text = b'' + while True: + str = bz2f.read(10) + if not str: + break + text += str + self.assertEqual(text, self.TEXT * 5) + def testRead100(self): - # "Test BZ2File.read(100)" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertEqual(bz2f.read(100), self.TEXT[:100]) def testPeek(self): - # "Test BZ2File.peek()" self.createTempFile() with BZ2File(self.filename) as bz2f: pdata = bz2f.peek() @@ -130,7 +148,6 @@ self.assertEqual(bz2f.read(), self.TEXT) def testReadInto(self): - # "Test BZ2File.readinto()" self.createTempFile() with BZ2File(self.filename) as bz2f: n = 128 @@ -143,32 +160,43 @@ self.assertEqual(b[:n], self.TEXT[-n:]) def testReadLine(self): - # "Test BZ2File.readline()" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertRaises(TypeError, bz2f.readline, None) - sio = BytesIO(self.TEXT) - for line in sio.readlines(): + for line in self.TEXT_LINES: + self.assertEqual(bz2f.readline(), line) + + def testReadLineMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + self.assertRaises(TypeError, bz2f.readline, None) + for line in self.TEXT_LINES * 5: self.assertEqual(bz2f.readline(), line) def testReadLines(self): - # "Test BZ2File.readlines()" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertRaises(TypeError, bz2f.readlines, None) - sio = BytesIO(self.TEXT) - self.assertEqual(bz2f.readlines(), sio.readlines()) + self.assertEqual(bz2f.readlines(), self.TEXT_LINES) + + def testReadLinesMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + self.assertRaises(TypeError, bz2f.readlines, None) + self.assertEqual(bz2f.readlines(), self.TEXT_LINES * 5) def testIterator(self): - # "Test iter(BZ2File)" self.createTempFile() with BZ2File(self.filename) as bz2f: - sio = BytesIO(self.TEXT) - self.assertEqual(list(iter(bz2f)), sio.readlines()) + self.assertEqual(list(iter(bz2f)), self.TEXT_LINES) + + def testIteratorMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + self.assertEqual(list(iter(bz2f)), self.TEXT_LINES * 5) def testClosedIteratorDeadlock(self): - # "Test that iteration on a closed bz2file releases the lock." - # http://bugs.python.org/issue3309 + # Issue #3309: Iteration on a closed BZ2File should release the lock. self.createTempFile() bz2f = BZ2File(self.filename) bz2f.close() @@ -178,7 +206,6 @@ self.assertRaises(ValueError, bz2f.readlines) def testWrite(self): - # "Test BZ2File.write()" with BZ2File(self.filename, "w") as bz2f: self.assertRaises(TypeError, bz2f.write) bz2f.write(self.TEXT) @@ -186,10 +213,9 @@ self.assertEqual(self.decompress(f.read()), self.TEXT) def testWriteChunks10(self): - # "Test BZ2File.write() with chunks of 10 bytes" with BZ2File(self.filename, "w") as bz2f: n = 0 - while 1: + while True: str = self.TEXT[n*10:(n+1)*10] if not str: break @@ -199,12 +225,11 @@ self.assertEqual(self.decompress(f.read()), self.TEXT) def testWriteLines(self): - # "Test BZ2File.writelines()" with BZ2File(self.filename, "w") as bz2f: self.assertRaises(TypeError, bz2f.writelines) - sio = BytesIO(self.TEXT) - bz2f.writelines(sio.readlines()) - # patch #1535500 + bz2f.writelines(self.TEXT_LINES) + # Issue #1535500: Calling writelines() on a closed BZ2File + # should raise an exception. self.assertRaises(ValueError, bz2f.writelines, ["a"]) with open(self.filename, 'rb') as f: self.assertEqual(self.decompress(f.read()), self.TEXT) @@ -217,39 +242,73 @@ self.assertRaises(IOError, bz2f.write, b"a") self.assertRaises(IOError, bz2f.writelines, [b"a"]) + def testAppend(self): + with BZ2File(self.filename, "w") as bz2f: + self.assertRaises(TypeError, bz2f.write) + bz2f.write(self.TEXT) + with BZ2File(self.filename, "a") as bz2f: + self.assertRaises(TypeError, bz2f.write) + bz2f.write(self.TEXT) + with open(self.filename, 'rb') as f: + self.assertEqual(self.decompress(f.read()), self.TEXT * 2) + def testSeekForward(self): - # "Test BZ2File.seek(150, 0)" self.createTempFile() with BZ2File(self.filename) as bz2f: self.assertRaises(TypeError, bz2f.seek) bz2f.seek(150) self.assertEqual(bz2f.read(), self.TEXT[150:]) + def testSeekForwardAcrossStreams(self): + self.createTempFile(streams=2) + with BZ2File(self.filename) as bz2f: + self.assertRaises(TypeError, bz2f.seek) + bz2f.seek(len(self.TEXT) + 150) + self.assertEqual(bz2f.read(), self.TEXT[150:]) + def testSeekBackwards(self): - # "Test BZ2File.seek(-150, 1)" self.createTempFile() with BZ2File(self.filename) as bz2f: bz2f.read(500) bz2f.seek(-150, 1) self.assertEqual(bz2f.read(), self.TEXT[500-150:]) + def testSeekBackwardsAcrossStreams(self): + self.createTempFile(streams=2) + with BZ2File(self.filename) as bz2f: + readto = len(self.TEXT) + 100 + while readto > 0: + readto -= len(bz2f.read(readto)) + bz2f.seek(-150, 1) + self.assertEqual(bz2f.read(), self.TEXT[100-150:] + self.TEXT) + def testSeekBackwardsFromEnd(self): - # "Test BZ2File.seek(-150, 2)" self.createTempFile() with BZ2File(self.filename) as bz2f: bz2f.seek(-150, 2) self.assertEqual(bz2f.read(), self.TEXT[len(self.TEXT)-150:]) + def testSeekBackwardsFromEndAcrossStreams(self): + self.createTempFile(streams=2) + with BZ2File(self.filename) as bz2f: + bz2f.seek(-1000, 2) + self.assertEqual(bz2f.read(), (self.TEXT * 2)[-1000:]) + def testSeekPostEnd(self): - # "Test BZ2File.seek(150000)" self.createTempFile() with BZ2File(self.filename) as bz2f: bz2f.seek(150000) self.assertEqual(bz2f.tell(), len(self.TEXT)) self.assertEqual(bz2f.read(), b"") + def testSeekPostEndMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + bz2f.seek(150000) + self.assertEqual(bz2f.tell(), len(self.TEXT) * 5) + self.assertEqual(bz2f.read(), b"") + def testSeekPostEndTwice(self): - # "Test BZ2File.seek(150000) twice" self.createTempFile() with BZ2File(self.filename) as bz2f: bz2f.seek(150000) @@ -257,34 +316,45 @@ self.assertEqual(bz2f.tell(), len(self.TEXT)) self.assertEqual(bz2f.read(), b"") + def testSeekPostEndTwiceMultiStream(self): + self.createTempFile(streams=5) + with BZ2File(self.filename) as bz2f: + bz2f.seek(150000) + bz2f.seek(150000) + self.assertEqual(bz2f.tell(), len(self.TEXT) * 5) + self.assertEqual(bz2f.read(), b"") + def testSeekPreStart(self): - # "Test BZ2File.seek(-150, 0)" self.createTempFile() with BZ2File(self.filename) as bz2f: bz2f.seek(-150) self.assertEqual(bz2f.tell(), 0) self.assertEqual(bz2f.read(), self.TEXT) + def testSeekPreStartMultiStream(self): + self.createTempFile(streams=2) + with BZ2File(self.filename) as bz2f: + bz2f.seek(-150) + self.assertEqual(bz2f.tell(), 0) + self.assertEqual(bz2f.read(), self.TEXT * 2) + def testFileno(self): - # "Test BZ2File.fileno()" self.createTempFile() with open(self.filename) as rawf: with BZ2File(fileobj=rawf) as bz2f: self.assertEqual(bz2f.fileno(), rawf.fileno()) def testOpenDel(self): - # "Test opening and deleting a file many times" self.createTempFile() for i in range(10000): o = BZ2File(self.filename) del o def testOpenNonexistent(self): - # "Test opening a nonexistent file" self.assertRaises(IOError, BZ2File, "/non/existent") - def testBug1191043(self): - # readlines() for files containing no newline + def testReadlinesNoNewline(self): + # Issue #1191043: readlines() fails on a file containing no newline. data = b'BZh91AY&SY\xd9b\x89]\x00\x00\x00\x03\x80\x04\x00\x02\x00\x0c\x00 \x00!\x9ah3M\x13<]\xc9\x14\xe1BCe\x8a%t' with open(self.filename, "wb") as f: f.write(data) @@ -296,7 +366,6 @@ self.assertEqual(xlines, [b'Test']) def testContextProtocol(self): - # BZ2File supports the context management protocol f = None with BZ2File(self.filename, "wb") as f: f.write(b"xxx") @@ -319,7 +388,7 @@ @unittest.skipUnless(threading, 'Threading required for this test.') def testThreading(self): - # Using a BZ2File from several threads doesn't deadlock (issue #7205). + # Issue #7205: Using a BZ2File from several threads shouldn't deadlock. data = b"1" * 2**20 nthreads = 10 with bz2.BZ2File(self.filename, 'wb') as f: @@ -332,8 +401,7 @@ for t in threads: t.join() - def testMixedIterationReads(self): - # "Test mixed iteration and reads." + def testMixedIterationAndReads(self): self.createTempFile() linelen = len(self.TEXT_LINES[0]) halflen = linelen // 2 @@ -351,17 +419,28 @@ next(bz2f) self.assertEqual(bz2f.readlines(), []) + def testMultiStreamOrdering(self): + # Test the ordering of streams when reading a multi-stream archive. + data1 = b"foo" * 1000 + data2 = b"bar" * 1000 + with BZ2File(self.filename, "w") as bz2f: + bz2f.write(data1) + with BZ2File(self.filename, "a") as bz2f: + bz2f.write(data2) + with BZ2File(self.filename) as bz2f: + self.assertEqual(bz2f.read(), data1 + data2) + + # Tests for a BZ2File wrapping another file object: + def testReadBytesIO(self): - # "Test BZ2File.read() with BytesIO source" - with BytesIO(self.getData()) as bio: + with BytesIO(self.DATA) as bio: with BZ2File(fileobj=bio) as bz2f: self.assertRaises(TypeError, bz2f.read, None) self.assertEqual(bz2f.read(), self.TEXT) self.assertFalse(bio.closed) def testPeekBytesIO(self): - # "Test BZ2File.peek() with BytesIO source" - with BytesIO(self.getData()) as bio: + with BytesIO(self.DATA) as bio: with BZ2File(fileobj=bio) as bz2f: pdata = bz2f.peek() self.assertNotEqual(len(pdata), 0) @@ -369,7 +448,6 @@ self.assertEqual(bz2f.read(), self.TEXT) def testWriteBytesIO(self): - # "Test BZ2File.write() with BytesIO destination" with BytesIO() as bio: with BZ2File(fileobj=bio, mode="w") as bz2f: self.assertRaises(TypeError, bz2f.write) @@ -378,16 +456,14 @@ self.assertFalse(bio.closed) def testSeekForwardBytesIO(self): - # "Test BZ2File.seek(150, 0) with BytesIO source" - with BytesIO(self.getData()) as bio: + with BytesIO(self.DATA) as bio: with BZ2File(fileobj=bio) as bz2f: self.assertRaises(TypeError, bz2f.seek) bz2f.seek(150) self.assertEqual(bz2f.read(), self.TEXT[150:]) def testSeekBackwardsBytesIO(self): - # "Test BZ2File.seek(-150, 1) with BytesIO source" - with BytesIO(self.getData()) as bio: + with BytesIO(self.DATA) as bio: with BZ2File(fileobj=bio) as bz2f: bz2f.read(500) bz2f.seek(-150, 1) @@ -395,7 +471,6 @@ class BZ2CompressorTest(BaseTest): def testCompress(self): - # "Test BZ2Compressor.compress()/flush()" bz2c = BZ2Compressor() self.assertRaises(TypeError, bz2c.compress) data = bz2c.compress(self.TEXT) @@ -403,11 +478,10 @@ self.assertEqual(self.decompress(data), self.TEXT) def testCompressChunks10(self): - # "Test BZ2Compressor.compress()/flush() with chunks of 10 bytes" bz2c = BZ2Compressor() n = 0 data = b'' - while 1: + while True: str = self.TEXT[n*10:(n+1)*10] if not str: break @@ -438,18 +512,16 @@ self.assertRaises(TypeError, BZ2Decompressor, 42) def testDecompress(self): - # "Test BZ2Decompressor.decompress()" bz2d = BZ2Decompressor() self.assertRaises(TypeError, bz2d.decompress) text = bz2d.decompress(self.DATA) self.assertEqual(text, self.TEXT) def testDecompressChunks10(self): - # "Test BZ2Decompressor.decompress() with chunks of 10 bytes" bz2d = BZ2Decompressor() text = b'' n = 0 - while 1: + while True: str = self.DATA[n*10:(n+1)*10] if not str: break @@ -458,7 +530,6 @@ self.assertEqual(text, self.TEXT) def testDecompressUnusedData(self): - # "Test BZ2Decompressor.decompress() with unused data" bz2d = BZ2Decompressor() unused_data = b"this is unused data" text = bz2d.decompress(self.DATA+unused_data) @@ -466,7 +537,6 @@ self.assertEqual(bz2d.unused_data, unused_data) def testEOFError(self): - # "Calling BZ2Decompressor.decompress() after EOS must raise EOFError" bz2d = BZ2Decompressor() text = bz2d.decompress(self.DATA) self.assertRaises(EOFError, bz2d.decompress, b"anything") @@ -492,24 +562,24 @@ "Test module functions" def testCompress(self): - # "Test compress() function" data = bz2.compress(self.TEXT) self.assertEqual(self.decompress(data), self.TEXT) def testDecompress(self): - # "Test decompress() function" text = bz2.decompress(self.DATA) self.assertEqual(text, self.TEXT) def testDecompressEmpty(self): - # "Test decompress() function with empty string" text = bz2.decompress(b"") self.assertEqual(text, b"") def testDecompressIncomplete(self): - # "Test decompress() function with incomplete data" self.assertRaises(ValueError, bz2.decompress, self.DATA[:-10]) + def testDecompressMultiStream(self): + text = bz2.decompress(self.DATA * 5) + self.assertEqual(text, self.TEXT * 5) + def test_main(): support.run_unittest( BZ2FileTest, @@ -521,5 +591,3 @@ if __name__ == '__main__': test_main() - -# vim:ts=4:sw=4 diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -190,18 +190,17 @@ idents = [] def callback(): - idents.append(_thread.get_ident()) + idents.append(threading.get_ident()) _testcapi._test_thread_state(callback) a = b = callback time.sleep(1) # Check our main thread is in the list exactly 3 times. - if idents.count(_thread.get_ident()) != 3: + if idents.count(threading.get_ident()) != 3: raise support.TestFailed( "Couldn't find main thread correctly in the list") if threading: - import _thread import time TestThreadState() t = threading.Thread(target=TestThreadState) diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py --- a/Lib/test/test_codecencodings_cn.py +++ b/Lib/test/test_codecencodings_cn.py @@ -50,6 +50,35 @@ ) has_iso10646 = True +class Test_HZ(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'hz' + tstring = test_multibytecodec_support.load_teststring('hz') + codectests = ( + # test '~\n' (3 lines) + (b'This sentence is in ASCII.\n' + b'The next sentence is in GB.~{<:Ky2;S{#,~}~\n' + b'~{NpJ)l6HK!#~}Bye.\n', + 'strict', + 'This sentence is in ASCII.\n' + 'The next sentence is in GB.' + '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002' + 'Bye.\n'), + # test '~\n' (4 lines) + (b'This sentence is in ASCII.\n' + b'The next sentence is in GB.~\n' + b'~{<:Ky2;S{#,NpJ)l6HK!#~}~\n' + b'Bye.\n', + 'strict', + 'This sentence is in ASCII.\n' + 'The next sentence is in GB.' + '\u5df1\u6240\u4e0d\u6b32\uff0c\u52ff\u65bd\u65bc\u4eba\u3002' + 'Bye.\n'), + # invalid bytes + (b'ab~cd', 'replace', 'ab\uFFFDd'), + (b'ab\xffcd', 'replace', 'ab\uFFFDcd'), + (b'ab~{\x81\x81\x41\x44~}cd', 'replace', 'ab\uFFFD\uFFFD\u804Acd'), + ) + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py new file mode 100644 --- /dev/null +++ b/Lib/test/test_codecencodings_iso2022.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# +# Codec encoding tests for ISO 2022 encodings. + +from test import support +from test import test_multibytecodec_support +import unittest + +COMMON_CODEC_TESTS = ( + # invalid bytes + (b'ab\xFFcd', 'replace', 'ab\uFFFDcd'), + (b'ab\x1Bdef', 'replace', 'ab\x1Bdef'), + (b'ab\x1B$def', 'replace', 'ab\uFFFD'), + ) + +class Test_ISO2022_JP(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp' + tstring = test_multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + ) + +class Test_ISO2022_JP2(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_jp_2' + tstring = test_multibytecodec_support.load_teststring('iso2022_jp') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'abdef'), + ) + +class Test_ISO2022_KR(test_multibytecodec_support.TestBase, unittest.TestCase): + encoding = 'iso2022_kr' + tstring = test_multibytecodec_support.load_teststring('iso2022_kr') + codectests = COMMON_CODEC_TESTS + ( + (b'ab\x1BNdef', 'replace', 'ab\x1BNdef'), + ) + + # iso2022_kr.txt cannot be used to test "chunk coding": the escape + # sequence is only written on the first line + def test_chunkcoding(self): + pass + +def test_main(): + support.run_unittest(__name__) + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -514,13 +514,11 @@ s1 = 'Hello\r\nworld\r\n' s = s1.encode(self.encoding) - try: - with open(support.TESTFN, 'wb') as fp: - fp.write(s) - with codecs.open(support.TESTFN, 'U', encoding=self.encoding) as reader: - self.assertEqual(reader.read(), s1) - finally: - support.unlink(support.TESTFN) + self.addCleanup(support.unlink, support.TESTFN) + with open(support.TESTFN, 'wb') as fp: + fp.write(s) + with codecs.open(support.TESTFN, 'U', encoding=self.encoding) as reader: + self.assertEqual(reader.read(), s1) class UTF16LETest(ReadTest): encoding = "utf-16-le" @@ -1624,6 +1622,7 @@ "utf-32", "utf-32-le", "utf-32-be") + self.addCleanup(support.unlink, support.TESTFN) for encoding in tests: # Check if the BOM is written only once with codecs.open(support.TESTFN, 'w+', encoding=encoding) as f: diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -181,12 +181,12 @@ self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__dict__', dir(p)) # verify instance has no dict self.assertNotIn('__weakref__', dir(p)) self.assertEqual(p, Point._make([11, 22])) # test _make classmethod self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method + self.assertEqual(vars(p), p._asdict()) # verify that vars() works try: p._replace(x=1, error=2) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1,6 +1,7 @@ import unittest import sys import _ast +import types from test import support class TestSpecifics(unittest.TestCase): @@ -433,6 +434,14 @@ ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '', 'exec') + @support.cpython_only + def test_same_filename_used(self): + s = """def f(): pass\ndef g(): pass""" + c = compile(s, "myfile", "exec") + for obj in c.co_consts: + if isinstance(obj, types.CodeType): + self.assertIs(obj.co_filename, c.co_filename) + def test_main(): support.run_unittest(TestSpecifics) diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -260,14 +260,14 @@ def test_timeout(self): future1 = self.executor.submit(mul, 6, 7) - future2 = self.executor.submit(time.sleep, 3) + future2 = self.executor.submit(time.sleep, 6) finished, pending = futures.wait( [CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, SUCCESSFUL_FUTURE, future1, future2], - timeout=1.5, + timeout=5, return_when=futures.ALL_COMPLETED) self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, @@ -357,8 +357,8 @@ results = [] try: for i in self.executor.map(time.sleep, - [0, 0, 3], - timeout=1.5): + [0, 0, 6], + timeout=5): results.append(i) except futures.TimeoutError: pass diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1587,6 +1587,7 @@ ("__floor__", math.floor, zero, set(), {}), ("__trunc__", math.trunc, zero, set(), {}), ("__ceil__", math.ceil, zero, set(), {}), + ("__dir__", dir, empty_seq, set(), {}), ] class Checker(object): @@ -1630,12 +1631,7 @@ for attr, obj in env.items(): setattr(X, attr, obj) setattr(X, name, ErrDescr()) - try: - runner(X()) - except MyException: - pass - else: - self.fail("{0!r} didn't raise".format(name)) + self.assertRaises(MyException, runner, X()) def test_specials(self): # Testing special operators... diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -170,6 +170,7 @@ '__contains__', '__delattr__', '__delitem__', + '__dir__', '__doc__', '__eq__', '__format__', diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -29,13 +29,14 @@ except (ValueError, resource_error): pass -def expected_traceback(lineno1, lineno2, header, count=1): +def expected_traceback(lineno1, lineno2, header, min_count=1): regex = header regex += ' File "", line %s in func\n' % lineno1 regex += ' File "", line %s in ' % lineno2 - if count != 1: - regex = (regex + '\n') * (count - 1) + regex - return '^' + regex + '$' + if 1 < min_count: + return '^' + (regex + '\n') * (min_count - 1) + regex + else: + return '^' + regex + '$' @contextmanager def temporary_filename(): @@ -371,7 +372,7 @@ faulthandler.dump_tracebacks_later(timeout, repeat=repeat, file=file) if cancel: faulthandler.cancel_dump_tracebacks_later() - time.sleep(timeout * 2.5) + time.sleep(timeout * 5) faulthandler.cancel_dump_tracebacks_later() timeout = {timeout} @@ -402,7 +403,7 @@ if repeat: count *= 2 header = r'Timeout \(%s\)!\nThread 0x[0-9a-f]+:\n' % timeout_str - regex = expected_traceback(9, 20, header, count=count) + regex = expected_traceback(9, 20, header, min_count=count) self.assertRegex(trace, regex) else: self.assertEqual(trace, '') diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -10,7 +10,7 @@ class TokenTests(unittest.TestCase): - def testBackslash(self): + def test_backslash(self): # Backslash means line continuation: x = 1 \ + 1 @@ -20,7 +20,7 @@ x = 0 self.assertEqual(x, 0, 'backslash ending comment') - def testPlainIntegers(self): + def test_plain_integers(self): self.assertEqual(type(000), type(0)) self.assertEqual(0xff, 255) self.assertEqual(0o377, 255) @@ -56,7 +56,7 @@ else: self.fail('Weird maxsize value %r' % maxsize) - def testLongIntegers(self): + def test_long_integers(self): x = 0 x = 0xffffffffffffffff x = 0Xffffffffffffffff @@ -66,7 +66,7 @@ x = 0b100000000000000000000000000000000000000000000000000000000000000000000 x = 0B111111111111111111111111111111111111111111111111111111111111111111111 - def testFloats(self): + def test_floats(self): x = 3.14 x = 314. x = 0.314 @@ -80,7 +80,7 @@ x = .3e14 x = 3.1e4 - def testStringLiterals(self): + def test_string_literals(self): x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y) x = '\''; y = "'"; self.assertTrue(len(x) == 1 and x == y and ord(x) == 39) x = '"'; y = "\""; self.assertTrue(len(x) == 1 and x == y and ord(x) == 34) @@ -120,11 +120,18 @@ ' self.assertEqual(x, y) - def testEllipsis(self): + def test_ellipsis(self): x = ... self.assertTrue(x is Ellipsis) self.assertRaises(SyntaxError, eval, ".. .") + def test_eof_error(self): + samples = ("def foo(", "\ndef foo(", "def foo(\n") + for s in samples: + with self.assertRaises(SyntaxError) as cm: + compile(s, "", "exec") + self.assertIn("unexpected EOF", str(cm.exception)) + class GrammarTests(unittest.TestCase): # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE @@ -136,11 +143,11 @@ # expr_input: testlist NEWLINE # XXX Hard to test -- used only in calls to input() - def testEvalInput(self): + def test_eval_input(self): # testlist ENDMARKER x = eval('1, 0 or 1') - def testFuncdef(self): + def test_funcdef(self): ### [decorators] 'def' NAME parameters ['->' test] ':' suite ### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE ### decorators: decorator+ @@ -324,7 +331,7 @@ check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))") - def testLambdef(self): + def test_lambdef(self): ### lambdef: 'lambda' [varargslist] ':' test l1 = lambda : 0 self.assertEqual(l1(), 0) @@ -346,7 +353,7 @@ ### stmt: simple_stmt | compound_stmt # Tested below - def testSimpleStmt(self): + def test_simple_stmt(self): ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): @@ -357,7 +364,7 @@ ### small_stmt: expr_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt # Tested below - def testExprStmt(self): + def test_expr_stmt(self): # (exprlist '=')* exprlist 1 1, 2, 3 @@ -370,7 +377,7 @@ check_syntax_error(self, "x + 1 = 1") check_syntax_error(self, "a + 1 = b + 2") - def testDelStmt(self): + def test_del_stmt(self): # 'del' exprlist abc = [1,2,3] x, y, z = abc @@ -379,18 +386,18 @@ del abc del x, y, (z, xyz) - def testPassStmt(self): + def test_pass_stmt(self): # 'pass' pass # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt # Tested below - def testBreakStmt(self): + def test_break_stmt(self): # 'break' while 1: break - def testContinueStmt(self): + def test_continue_stmt(self): # 'continue' i = 1 while i: i = 0; continue @@ -442,7 +449,7 @@ self.fail("continue then break in try/except in loop broken!") test_inner() - def testReturn(self): + def test_return(self): # 'return' [testlist] def g1(): return def g2(): return 1 @@ -450,17 +457,17 @@ x = g2() check_syntax_error(self, "class foo:return 1") - def testYield(self): + def test_yield(self): check_syntax_error(self, "class foo:yield 1") - def testRaise(self): + def test_raise(self): # 'raise' test [',' test] try: raise RuntimeError('just testing') except RuntimeError: pass try: raise KeyboardInterrupt except KeyboardInterrupt: pass - def testImport(self): + def test_import(self): # 'import' dotted_as_names import sys import time, sys @@ -473,13 +480,13 @@ from sys import (path, argv) from sys import (path, argv,) - def testGlobal(self): + def test_global(self): # 'global' NAME (',' NAME)* global a global a, b global one, two, three, four, five, six, seven, eight, nine, ten - def testNonlocal(self): + def test_nonlocal(self): # 'nonlocal' NAME (',' NAME)* x = 0 y = 0 @@ -487,7 +494,7 @@ nonlocal x nonlocal x, y - def testAssert(self): + def test_assert(self): # assertTruestmt: 'assert' test [',' test] assert 1 assert 1, 1 @@ -504,7 +511,7 @@ ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef # Tested below - def testIf(self): + def test_if(self): # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] if 1: pass if 1: pass @@ -517,7 +524,7 @@ elif 0: pass else: pass - def testWhile(self): + def test_while(self): # 'while' test ':' suite ['else' ':' suite] while 0: pass while 0: pass @@ -532,7 +539,7 @@ x = 2 self.assertEqual(x, 2) - def testFor(self): + def test_for(self): # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] for i in 1, 2, 3: pass for i, j, k in (): pass @@ -559,7 +566,7 @@ result.append(x) self.assertEqual(result, [1, 2, 3]) - def testTry(self): + def test_try(self): ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ### | 'try' ':' suite 'finally' ':' suite ### except_clause: 'except' [expr ['as' expr]] @@ -582,7 +589,7 @@ try: pass finally: pass - def testSuite(self): + def test_suite(self): # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT if 1: pass if 1: @@ -597,7 +604,7 @@ pass # - def testTest(self): + def test_test(self): ### and_test ('or' and_test)* ### and_test: not_test ('and' not_test)* ### not_test: 'not' not_test | comparison @@ -608,7 +615,7 @@ if not 1 and 1 and 1: pass if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass - def testComparison(self): + def test_comparison(self): ### comparison: expr (comp_op expr)* ### comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' if 1: pass @@ -625,36 +632,36 @@ if 1 not in (): pass if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass - def testBinaryMaskOps(self): + def test_binary_mask_ops(self): x = 1 & 1 x = 1 ^ 1 x = 1 | 1 - def testShiftOps(self): + def test_shift_ops(self): x = 1 << 1 x = 1 >> 1 x = 1 << 1 >> 1 - def testAdditiveOps(self): + def test_additive_ops(self): x = 1 x = 1 + 1 x = 1 - 1 - 1 x = 1 - 1 + 1 - 1 + 1 - def testMultiplicativeOps(self): + def test_multiplicative_ops(self): x = 1 * 1 x = 1 / 1 x = 1 % 1 x = 1 / 1 * 1 % 1 - def testUnaryOps(self): + def test_unary_ops(self): x = +1 x = -1 x = ~1 x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 x = -1*1/1 + 1*1 - ---1*1 - def testSelectors(self): + def test_selectors(self): ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ### subscript: expr | [expr] ':' [expr] @@ -684,7 +691,7 @@ L.sort(key=lambda x: x if isinstance(x, tuple) else ()) self.assertEqual(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') - def testAtoms(self): + def test_atoms(self): ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictsetmaker] '}' | NAME | NUMBER | STRING ### dictsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) @@ -719,7 +726,7 @@ ### testlist: test (',' test)* [','] # These have been exercised enough above - def testClassdef(self): + def test_classdef(self): # 'class' NAME ['(' [testlist] ')'] ':' suite class B: pass class B2(): pass @@ -738,14 +745,14 @@ @class_decorator class G: pass - def testDictcomps(self): + def test_dictcomps(self): # dictorsetmaker: ( (test ':' test (comp_for | # (',' test ':' test)* [','])) | # (test (comp_for | (',' test)* [','])) ) nums = [1, 2, 3] self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) - def testListcomps(self): + def test_listcomps(self): # list comprehension tests nums = [1, 2, 3, 4, 5] strs = ["Apple", "Banana", "Coconut"] @@ -808,7 +815,7 @@ self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]) - def testGenexps(self): + def test_genexps(self): # generator expression tests g = ([x for x in range(10)] for x in range(1)) self.assertEqual(next(g), [x for x in range(10)]) @@ -843,7 +850,7 @@ check_syntax_error(self, "foo(x for x in range(10), 100)") check_syntax_error(self, "foo(100, x for x in range(10))") - def testComprehensionSpecials(self): + def test_comprehension_specials(self): # test for outmost iterable precomputation x = 10; g = (i for i in range(x)); x = 5 self.assertEqual(len(list(g)), 10) @@ -882,7 +889,7 @@ with manager() as x, manager(): pass - def testIfElseExpr(self): + def test_if_else_expr(self): # Test ifelse expressions in various cases def _checkeval(msg, ret): "helper to check that evaluation of expressions is done correctly" diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -833,14 +833,17 @@ # Inject some None's in there to simulate EWOULDBLOCK rawio = self.MockRawIO((b"abc", b"d", None, b"efg", None, None, None)) bufio = self.tp(rawio) - self.assertEqual(b"abcd", bufio.read(6)) self.assertEqual(b"e", bufio.read(1)) self.assertEqual(b"fg", bufio.read()) self.assertEqual(b"", bufio.peek(1)) - self.assertTrue(None is bufio.read()) + self.assertIsNone(bufio.read()) self.assertEqual(b"", bufio.read()) + rawio = self.MockRawIO((b"a", None, None)) + self.assertEqual(b"a", rawio.readall()) + self.assertIsNone(rawio.readall()) + def test_read_past_eof(self): rawio = self.MockRawIO((b"abc", b"d", b"efg")) bufio = self.tp(rawio) @@ -2512,6 +2515,8 @@ self.assertRaises(ValueError, f.read) if hasattr(f, "read1"): self.assertRaises(ValueError, f.read1, 1024) + if hasattr(f, "readall"): + self.assertRaises(ValueError, f.readall) if hasattr(f, "readinto"): self.assertRaises(ValueError, f.readinto, bytearray(1024)) self.assertRaises(ValueError, f.readline) @@ -2678,7 +2683,7 @@ # The buffered IO layer must check for pending signal # handlers, which in this case will invoke alarm_interrupt(). self.assertRaises(ZeroDivisionError, - wio.write, item * (1024 * 1024)) + wio.write, item * (support.PIPE_MAX_SIZE // len(item))) t.join() # We got one byte, get another one and check that it isn't a # repeat of the first one. diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -888,19 +888,35 @@ before calling :meth:`start`, so that the server will set up the socket and listen on it. """ - def __init__(self, addr, handler, poll_interval=0.5, bind_and_activate=True): + def __init__(self, addr, handler, poll_interval=0.5, + bind_and_activate=True): class DelegatingUDPRequestHandler(DatagramRequestHandler): def handle(self): self.server._handler(self) - ThreadingUDPServer.__init__(self, addr, DelegatingUDPRequestHandler, + + def finish(self): + data = self.wfile.getvalue() + if data: + try: + super(DelegatingUDPRequestHandler, self).finish() + except socket.error: + if not self.server._closed: + raise + + ThreadingUDPServer.__init__(self, addr, + DelegatingUDPRequestHandler, bind_and_activate) ControlMixin.__init__(self, handler, poll_interval) + self._closed = False def server_bind(self): super(TestUDPServer, self).server_bind() self.port = self.socket.getsockname()[1] + def server_close(self): + super(TestUDPServer, self).server_close() + self._closed = True # - end of server_helper section @@ -3570,7 +3586,7 @@ r = logging.makeLogRecord({'msg': 'testing'}) fh.emit(r) self.assertLogFile(self.fn) - time.sleep(1.0) + time.sleep(1.01) # just a little over a second ... fh.emit(r) fh.close() # At this point, we should have a recent rotated file which we diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -5,6 +5,7 @@ import sys import unittest import os +import types class HelperMixin: def helper(self, sample, *extra): @@ -113,6 +114,22 @@ codes = (ExceptionTestCase.test_exceptions.__code__,) * count marshal.loads(marshal.dumps(codes)) + def test_different_filenames(self): + co1 = compile("x", "f1", "exec") + co2 = compile("y", "f2", "exec") + co1, co2 = marshal.loads(marshal.dumps((co1, co2))) + self.assertEqual(co1.co_filename, "f1") + self.assertEqual(co2.co_filename, "f2") + + @support.cpython_only + def test_same_filename_used(self): + s = """def f(): pass\ndef g(): pass""" + co = compile(s, "myfile", "exec") + co = marshal.loads(marshal.dumps(co)) + for obj in co.co_consts: + if isinstance(obj, types.CodeType): + self.assertIs(co.co_filename, obj.co_filename) + class ContainerTestCase(unittest.TestCase, HelperMixin): d = {'astring': 'foo at bar.baz.spam', 'afloat': 7283.43, diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2,6 +2,7 @@ # XXXX Should not do tests around zero only from test.support import run_unittest, verbose, requires_IEEE_754 +from test import support import unittest import math import os @@ -669,9 +670,8 @@ self.assertTrue(math.isnan(math.log2(NAN))) @requires_IEEE_754 - @unittest.skipIf(sys.platform == 'darwin' - and platform.mac_ver()[0].startswith('10.4.'), - 'Mac OS X Tiger log2() is not accurate enough') + # log2() is not accurate enough on Mac OS X Tiger (10.4) + @support.requires_mac_ver(10, 5) def testLog2Exact(self): # Check that we get exact equality for log2 of powers of 2. actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -256,6 +256,41 @@ # Any ISO 2022 codec will cause the segfault myunichr(x).encode('iso_2022_jp', 'ignore') +class TestStateful(unittest.TestCase): + text = '\u4E16\u4E16' + encoding = 'iso-2022-jp' + expected = b'\x1b$B@$@$' + reset = b'\x1b(B' + expected_reset = expected + reset + + def test_encode(self): + self.assertEqual(self.text.encode(self.encoding), self.expected_reset) + + def test_incrementalencoder(self): + encoder = codecs.getincrementalencoder(self.encoding)() + output = b''.join( + encoder.encode(char) + for char in self.text) + self.assertEqual(output, self.expected) + self.assertEqual(encoder.encode('', final=True), self.reset) + self.assertEqual(encoder.encode('', final=True), b'') + + def test_incrementalencoder_final(self): + encoder = codecs.getincrementalencoder(self.encoding)() + last_index = len(self.text) - 1 + output = b''.join( + encoder.encode(char, index == last_index) + for index, char in enumerate(self.text)) + self.assertEqual(output, self.expected_reset) + self.assertEqual(encoder.encode('', final=True), b'') + +class TestHZStateful(TestStateful): + text = '\u804a\u804a' + encoding = 'hz' + expected = b'~{ADAD' + reset = b'~}' + expected_reset = expected + reset + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_multibytecodec_support.py b/Lib/test/test_multibytecodec_support.py --- a/Lib/test/test_multibytecodec_support.py +++ b/Lib/test/test_multibytecodec_support.py @@ -58,9 +58,16 @@ result = func(source, scheme)[0] if func is self.decode: self.assertTrue(type(result) is str, type(result)) + self.assertEqual(result, expected, + '%a.decode(%r, %r)=%a != %a' + % (source, self.encoding, scheme, result, + expected)) else: self.assertTrue(type(result) is bytes, type(result)) - self.assertEqual(result, expected) + self.assertEqual(result, expected, + '%a.encode(%r, %r)=%a != %a' + % (source, self.encoding, scheme, result, + expected)) else: self.assertRaises(UnicodeError, func, source, scheme) @@ -277,6 +284,7 @@ pass_enctest = [] pass_dectest = [] supmaps = [] + codectests = [] def __init__(self, *args, **kw): unittest.TestCase.__init__(self, *args, **kw) @@ -346,6 +354,30 @@ if (csetch, unich) not in self.pass_dectest: self.assertEqual(str(csetch, self.encoding), unich) + def test_errorhandle(self): + for source, scheme, expected in self.codectests: + if isinstance(source, bytes): + func = source.decode + else: + func = source.encode + if expected: + if isinstance(source, bytes): + result = func(self.encoding, scheme) + self.assertTrue(type(result) is str, type(result)) + self.assertEqual(result, expected, + '%a.decode(%r, %r)=%a != %a' + % (source, self.encoding, scheme, result, + expected)) + else: + result = func(self.encoding, scheme) + self.assertTrue(type(result) is bytes, type(result)) + self.assertEqual(result, expected, + '%a.encode(%r, %r)=%a != %a' + % (source, self.encoding, scheme, result, + expected)) + else: + self.assertRaises(UnicodeError, func, self.encoding, scheme) + def load_teststring(name): dir = os.path.join(os.path.dirname(__file__), 'cjkencodings') with open(os.path.join(dir, name + '.txt'), 'rb') as f: diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -614,6 +614,13 @@ # XXX tests for pickling and unpickling of ST objects should go here +class OtherParserCase(unittest.TestCase): + + def test_two_args_to_expr(self): + # See bug #12264 + with self.assertRaises(TypeError): + parser.expr("a", "b") + def test_main(): support.run_unittest( @@ -622,6 +629,7 @@ CompileTestCase, ParserStackLimitTestCase, STObjectTestCase, + OtherParserCase, ) diff --git a/Lib/test/test_pep292.py b/Lib/test/test_pep292.py --- a/Lib/test/test_pep292.py +++ b/Lib/test/test_pep292.py @@ -42,19 +42,6 @@ s = Template('$who likes $$') eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $') - def test_invalid(self): - class MyPattern(Template): - pattern = r""" - (?: - (?P) | - (?P%(delim)s) | - @(?P%(id)s) | - @{(?P%(id)s)} - ) - """ - s = MyPattern('$') - self.assertRaises(ValueError, s.substitute, dict()) - def test_percents(self): eq = self.assertEqual s = Template('%(foo)s $foo ${foo}') @@ -172,6 +159,26 @@ val = t.safe_substitute({'location': 'Cleveland'}) self.assertEqual(val, 'PyCon in Cleveland') + def test_invalid_with_no_lines(self): + # The error formatting for invalid templates + # has a special case for no data that the default + # pattern can't trigger (always has at least '$') + # So we craft a pattern that is always invalid + # with no leading data. + class MyTemplate(Template): + pattern = r""" + (?P) | + unreachable( + (?P) | + (?P) | + (?P) + ) + """ + s = MyTemplate('') + with self.assertRaises(ValueError) as err: + s.substitute({}) + self.assertIn('line 1, col 1', str(err.exception)) + def test_unicode_values(self): s = Template('$who likes $what') d = dict(who='t\xffm', what='f\xfe\fed') diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -175,6 +175,32 @@ self.assertEqual(test1, result1) self.assertEqual(test2, result2) + def test_invalidarray(self): + for i in ["key inside an array", + "key inside an array23", + "key inside an array3"]: + self.assertRaises(ValueError, plistlib.readPlistFromBytes, + ("%s"%i).encode()) + + def test_invaliddict(self): + for i in ["kcompound key", + "single key", + "missing key", + "k1v15.3" + "k1k2double key"]: + self.assertRaises(ValueError, plistlib.readPlistFromBytes, + ("%s"%i).encode()) + self.assertRaises(ValueError, plistlib.readPlistFromBytes, + ("%s"%i).encode()) + + def test_invalidinteger(self): + self.assertRaises(ValueError, plistlib.readPlistFromBytes, + b"not integer") + + def test_invalidreal(self): + self.assertRaises(ValueError, plistlib.readPlistFromBytes, + b"not real") + def test_main(): support.run_unittest(TestPlistlib) diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -309,6 +309,7 @@ fp2.close() @unittest.skipUnless(hasattr(os, 'O_CLOEXEC'), "needs os.O_CLOEXEC") + @support.requires_linux_version(2, 6, 23) def test_oscloexec(self): fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC) self.addCleanup(os.close, fd) @@ -474,6 +475,32 @@ os.close(reader) os.close(writer) + @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()") + @support.requires_linux_version(2, 6, 27) + def test_pipe2(self): + self.assertRaises(TypeError, os.pipe2, 'DEADBEEF') + self.assertRaises(TypeError, os.pipe2, 0, 0) + + # try calling without flag, like os.pipe() + r, w = os.pipe2() + os.close(r) + os.close(w) + + # test flags + r, w = os.pipe2(os.O_CLOEXEC|os.O_NONBLOCK) + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFD) & fcntl.FD_CLOEXEC) + self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFD) & fcntl.FD_CLOEXEC) + # try reading from an empty pipe: this should fail, not block + self.assertRaises(OSError, os.read, r, 1) + # try a write big enough to fill-up the pipe: this should either + # fail or perform a partial write, not block + try: + os.write(w, b'x' * support.PIPE_MAX_SIZE) + except OSError: + pass + def test_utime(self): if hasattr(posix, 'utime'): now = time.time() diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -226,10 +226,17 @@ TIMEOUT_FULL = 10 TIMEOUT_HALF = 5 + def handler(self, signum, frame): + pass + def check_signum(self, *signals): data = os.read(self.read, len(signals)+1) raised = struct.unpack('%uB' % len(data), data) - self.assertSequenceEqual(raised, signals) + # We don't care of the signal delivery order (it's not portable or + # reliable) + raised = set(raised) + signals = set(signals) + self.assertEqual(raised, signals) def test_wakeup_fd_early(self): import select @@ -259,16 +266,38 @@ self.check_signum(signal.SIGALRM) def test_signum(self): - old_handler = signal.signal(signal.SIGUSR1, lambda x,y:None) + old_handler = signal.signal(signal.SIGUSR1, self.handler) self.addCleanup(signal.signal, signal.SIGUSR1, old_handler) os.kill(os.getpid(), signal.SIGUSR1) os.kill(os.getpid(), signal.SIGALRM) self.check_signum(signal.SIGUSR1, signal.SIGALRM) + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') + @unittest.skipUnless(hasattr(signal, 'pthread_kill'), + 'need signal.pthread_kill()') + def test_pending(self): + signum1 = signal.SIGUSR1 + signum2 = signal.SIGUSR2 + tid = threading.current_thread().ident + + old_handler = signal.signal(signum1, self.handler) + self.addCleanup(signal.signal, signum1, old_handler) + old_handler = signal.signal(signum2, self.handler) + self.addCleanup(signal.signal, signum2, old_handler) + + signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2)) + signal.pthread_kill(tid, signum1) + signal.pthread_kill(tid, signum2) + # Unblocking the 2 signals calls the C signal handler twice + signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2)) + + self.check_signum(signum1, signum2) + def setUp(self): import fcntl - self.alrm = signal.signal(signal.SIGALRM, lambda x,y:None) + self.alrm = signal.signal(signal.SIGALRM, self.handler) self.read, self.write = os.pipe() flags = fcntl.fcntl(self.write, fcntl.F_GETFL, 0) flags = flags | os.O_NONBLOCK @@ -529,7 +558,7 @@ def kill(self, signum): if self.has_pthread_kill: - tid = threading.current_thread().ident + tid = threading.get_ident() signal.pthread_kill(tid, signum) else: pid = os.getpid() @@ -561,7 +590,7 @@ 'need signal.pthread_kill()') def test_pthread_kill(self): signum = signal.SIGUSR1 - current = threading.current_thread().ident + current = threading.get_ident() old_handler = signal.signal(signum, self.handler) self.addCleanup(signal.signal, signum, old_handler) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -24,14 +24,6 @@ except ImportError: fcntl = False -def linux_version(): - try: - # platform.release() is something like '2.6.33.7-desktop-2mnb' - version_string = platform.release().split('-')[0] - return tuple(map(int, version_string.split('.'))) - except ValueError: - return 0, 0, 0 - HOST = support.HOST MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') ## test unicode string and carriage return @@ -1031,11 +1023,8 @@ pass if hasattr(socket, "SOCK_NONBLOCK"): + @support.requires_linux_version(2, 6, 28) def testInitNonBlocking(self): - v = linux_version() - if v < (2, 6, 28): - self.skipTest("Linux kernel 2.6.28 or higher required, not %s" - % ".".join(map(str, v))) # reinit server socket self.serv.close() self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM | @@ -2009,11 +1998,8 @@ "SOCK_CLOEXEC not defined") @unittest.skipUnless(fcntl, "module fcntl not available") class CloexecConstantTest(unittest.TestCase): + @support.requires_linux_version(2, 6, 28) def test_SOCK_CLOEXEC(self): - v = linux_version() - if v < (2, 6, 28): - self.skipTest("Linux kernel 2.6.28 or higher required, not %s" - % ".".join(map(str, v))) with socket.socket(socket.AF_INET, socket.SOCK_STREAM | socket.SOCK_CLOEXEC) as s: self.assertTrue(s.type & socket.SOCK_CLOEXEC) @@ -2031,11 +2017,8 @@ self.assertFalse(s.type & socket.SOCK_NONBLOCK) self.assertEqual(s.gettimeout(), None) + @support.requires_linux_version(2, 6, 28) def test_SOCK_NONBLOCK(self): - v = linux_version() - if v < (2, 6, 28): - self.skipTest("Linux kernel 2.6.28 or higher required, not %s" - % ".".join(map(str, v))) # a lot of it seems silly and redundant, but I wanted to test that # changing back and forth worked ok with socket.socket(socket.AF_INET, diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -102,6 +102,16 @@ sys.stdout.write("\n RAND_status is %d (%s)\n" % (v, (v and "sufficient randomness") or "insufficient randomness")) + + data, is_cryptographic = ssl.RAND_pseudo_bytes(16) + self.assertEqual(len(data), 16) + self.assertEqual(is_cryptographic, v == 1) + if v: + data = ssl.RAND_bytes(16) + self.assertEqual(len(data), 16) + else: + self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16) + try: ssl.RAND_egd(1) except TypeError: diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py --- a/Lib/test/test_string.py +++ b/Lib/test/test_string.py @@ -26,15 +26,38 @@ self.assertEqual(string.capwords('\taBc\tDeF\t'), 'Abc Def') self.assertEqual(string.capwords('\taBc\tDeF\t', '\t'), '\tAbc\tDef\t') - def test_formatter(self): + def test_basic_formatter(self): fmt = string.Formatter() self.assertEqual(fmt.format("foo"), "foo") - self.assertEqual(fmt.format("foo{0}", "bar"), "foobar") self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") + + def test_conversion_specifiers(self): + fmt = string.Formatter() self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") + self.assertEqual(fmt.format("{0!s}", 'test'), 'test') + self.assertRaises(ValueError, fmt.format, "{0!h}", 'test') - # override get_value ############################################ + def test_name_lookup(self): + fmt = string.Formatter() + class AnyAttr: + def __getattr__(self, attr): + return attr + x = AnyAttr() + self.assertEqual(fmt.format("{0.lumber}{0.jack}", x), 'lumberjack') + with self.assertRaises(AttributeError): + fmt.format("{0.lumber}{0.jack}", '') + + def test_index_lookup(self): + fmt = string.Formatter() + lookup = ["eggs", "and", "spam"] + self.assertEqual(fmt.format("{0[2]}{0[0]}", lookup), 'spameggs') + with self.assertRaises(IndexError): + fmt.format("{0[2]}{0[0]}", []) + with self.assertRaises(KeyError): + fmt.format("{0[2]}{0[0]}", {}) + + def test_override_get_value(self): class NamespaceFormatter(string.Formatter): def __init__(self, namespace={}): string.Formatter.__init__(self) @@ -54,7 +77,7 @@ self.assertEqual(fmt.format("{greeting}, world!"), 'hello, world!') - # override format_field ######################################### + def test_override_format_field(self): class CallFormatter(string.Formatter): def format_field(self, value, format_spec): return format(value(), format_spec) @@ -63,18 +86,18 @@ self.assertEqual(fmt.format('*{0}*', lambda : 'result'), '*result*') - # override convert_field ######################################## + def test_override_convert_field(self): class XFormatter(string.Formatter): def convert_field(self, value, conversion): if conversion == 'x': return None - return super(XFormatter, self).convert_field(value, conversion) + return super().convert_field(value, conversion) fmt = XFormatter() self.assertEqual(fmt.format("{0!r}:{0!x}", 'foo', 'foo'), "'foo':None") - # override parse ################################################ + def test_override_parse(self): class BarFormatter(string.Formatter): # returns an iterable that contains tuples of the form: # (literal_text, field_name, format_spec, conversion) @@ -90,7 +113,7 @@ fmt = BarFormatter() self.assertEqual(fmt.format('*|+0:^10s|*', 'foo'), '* foo *') - # test all parameters used + def test_check_unused_args(self): class CheckAllUsedFormatter(string.Formatter): def check_unused_args(self, used_args, args, kwargs): # Track which arguments actually got used @@ -112,28 +135,13 @@ self.assertRaises(ValueError, fmt.format, "{0}", 10, 20, i=100) self.assertRaises(ValueError, fmt.format, "{i}", 10, 20, i=100) - def test_vformat_assert(self): - cls = string.Formatter() - kwargs = { - "i": 100 - } - self.assertRaises(ValueError, cls._vformat, - cls.format, "{0}", kwargs, set(), -2) - - def test_convert_field(self): - cls = string.Formatter() - self.assertEqual(cls.format("{0!s}", 'foo'), 'foo') - self.assertRaises(ValueError, cls.format, "{0!h}", 'foo') - - def test_get_field(self): - cls = string.Formatter() - class MyClass: - name = 'lumberjack' - x = MyClass() - self.assertEqual(cls.format("{0.name}", x), 'lumberjack') - - lookup = ["eggs", "and", "spam"] - self.assertEqual(cls.format("{0[2]}", lookup), 'spam') + def test_vformat_recursion_limit(self): + fmt = string.Formatter() + args = () + kwargs = dict(i=100) + with self.assertRaises(ValueError) as err: + fmt._vformat("{i}", args, kwargs, set(), -1) + self.assertIn("recursion", str(err.exception)) def test_main(): diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -146,6 +146,16 @@ env=newenv) self.assertEqual(rc, 1) + def test_invalid_args(self): + # Popen() called with invalid arguments should raise TypeError + # but Popen.__del__ should not complain (issue #12085) + with support.captured_stderr() as s: + self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1) + argcount = subprocess.Popen.__init__.__code__.co_argcount + too_many_args = [0] * (argcount + 1) + self.assertRaises(TypeError, subprocess.Popen, *too_many_args) + self.assertEqual(s.getvalue(), '') + def test_stdin_none(self): # .stdin is None when not redirected p = subprocess.Popen([sys.executable, "-c", 'print("banana")'], @@ -489,24 +499,21 @@ # This test will probably deadlock rather than fail, if # communicate() does not work properly. x, y = os.pipe() - if mswindows: - pipe_buf = 512 - else: - pipe_buf = os.fpathconf(x, "PC_PIPE_BUF") os.close(x) os.close(y) p = subprocess.Popen([sys.executable, "-c", 'import sys,os;' 'sys.stdout.write(sys.stdin.read(47));' - 'sys.stderr.write("xyz"*%d);' - 'sys.stdout.write(sys.stdin.read())' % pipe_buf], + 'sys.stderr.write("x" * %d);' + 'sys.stdout.write(sys.stdin.read())' % + support.PIPE_MAX_SIZE], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self.addCleanup(p.stdout.close) self.addCleanup(p.stderr.close) self.addCleanup(p.stdin.close) - string_to_write = b"abc"*pipe_buf + string_to_write = b"a" * support.PIPE_MAX_SIZE (stdout, stderr) = p.communicate(string_to_write) self.assertEqual(stdout, string_to_write) @@ -1274,6 +1281,11 @@ "Some fds were left open") self.assertIn(1, remaining_fds, "Subprocess failed") + # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file + # descriptor of a pipe closed in the parent process is valid in the + # child process according to fstat(), but the mode of the file + # descriptor is invalid, and read or write raise an error. + @support.requires_mac_ver(10, 5) def test_pass_fds(self): fd_status = support.findfile("fd_status.py", subdir="subprocessdata") @@ -1495,20 +1507,6 @@ ProcessTestCase.tearDown(self) - at unittest.skipUnless(getattr(subprocess, '_posixsubprocess', False), - "_posixsubprocess extension module not found.") -class ProcessTestCasePOSIXPurePython(ProcessTestCase, POSIXProcessTestCase): - def setUp(self): - subprocess._posixsubprocess = None - ProcessTestCase.setUp(self) - POSIXProcessTestCase.setUp(self) - - def tearDown(self): - subprocess._posixsubprocess = sys.modules['_posixsubprocess'] - POSIXProcessTestCase.tearDown(self) - ProcessTestCase.tearDown(self) - - class HelperFunctionTests(unittest.TestCase): @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows") def test_eintr_retry_call(self): @@ -1617,7 +1615,6 @@ unit_tests = (ProcessTestCase, POSIXProcessTestCase, Win32ProcessTestCase, - ProcessTestCasePOSIXPurePython, CommandTests, ProcessTestCaseNoPoll, HelperFunctionTests, diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -343,7 +343,7 @@ # Test sys._current_frames() in a WITH_THREADS build. @test.support.reap_threads def current_frames_with_threads(self): - import threading, _thread + import threading import traceback # Spawn a thread that blocks at a known place. Then the main @@ -357,7 +357,7 @@ g456() def g456(): - thread_info.append(_thread.get_ident()) + thread_info.append(threading.get_ident()) entered_g.set() leave_g.wait() @@ -373,7 +373,7 @@ d = sys._current_frames() - main_id = _thread.get_ident() + main_id = threading.get_ident() self.assertIn(main_id, d) self.assertIn(thread_id, d) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -1,9 +1,3 @@ -"""Tests for 'site'. - -Tests assume the initial paths in sys.path once the interpreter has begun -executing have not been removed. - -""" import unittest import sys import os @@ -20,13 +14,12 @@ _get_default_scheme, _expand_vars, get_scheme_names, get_config_var, _main) + class TestSysConfig(unittest.TestCase): def setUp(self): - """Make a copy of sys.path""" super(TestSysConfig, self).setUp() self.sys_path = sys.path[:] - self.makefile = None # patching os.uname if hasattr(os, 'uname'): self.uname = os.uname @@ -53,10 +46,7 @@ self._added_envvars.append(var) def tearDown(self): - """Restore sys.path""" sys.path[:] = self.sys_path - if self.makefile is not None: - os.unlink(self.makefile) self._cleanup_testfn() if self.uname is not None: os.uname = self.uname @@ -145,8 +135,6 @@ ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' 'root:xnu-792.25.20~1/RELEASE_I386'), 'PowerPC')) - - get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' @@ -161,7 +149,6 @@ finally: sys.maxsize = maxint - self._set_uname(('Darwin', 'macziade', '8.11.1', ('Darwin Kernel Version 8.11.1: ' 'Wed Oct 10 18:23:28 PDT 2007; ' @@ -219,9 +206,9 @@ get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' '/Developer/SDKs/MacOSX10.4u.sdk ' '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3'%(arch,)) + '-dynamic -DNDEBUG -g -O3' % arch) - self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,)) + self.assertEqual(get_platform(), 'macosx-10.4-%s' % arch) # linux debian sarge os.name = 'posix' @@ -239,12 +226,6 @@ config_h = sysconfig.get_config_h_filename() self.assertTrue(os.path.isfile(config_h), config_h) - @unittest.skipIf(sys.platform.startswith('win'), - 'Test is not Windows compatible') - def test_get_makefile_filename(self): - makefile = sysconfig.get_makefile_filename() - self.assertTrue(os.path.isfile(makefile), makefile) - def test_get_scheme_names(self): wanted = ('nt', 'nt_user', 'os2', 'os2_home', 'osx_framework_user', 'posix_home', 'posix_prefix', 'posix_user') @@ -295,7 +276,6 @@ self.assertIn(ldflags, ldshared) - @unittest.skipUnless(sys.platform == "darwin", "test only relevant on MacOSX") def test_platform_in_subprocess(self): my_platform = sysconfig.get_platform() @@ -321,7 +301,6 @@ self.assertEqual(status, 0) self.assertEqual(my_platform, test_platform) - # Test with MACOSX_DEPLOYMENT_TARGET in the environment, and # using a value that is unlikely to be the default one. env = os.environ.copy() @@ -342,10 +321,34 @@ self.assertEqual(my_platform, test_platform) +class MakefileTests(unittest.TestCase): + + @unittest.skipIf(sys.platform.startswith('win'), + 'Test is not Windows compatible') + def test_get_makefile_filename(self): + makefile = sysconfig.get_makefile_filename() + self.assertTrue(os.path.isfile(makefile), makefile) + + def test_parse_makefile(self): + self.addCleanup(unlink, TESTFN) + with open(TESTFN, "w") as makefile: + print("var1=a$(VAR2)", file=makefile) + print("VAR2=b$(var3)", file=makefile) + print("var3=42", file=makefile) + print("var4=$/invalid", file=makefile) + print("var5=dollar$$5", file=makefile) + vars = sysconfig._parse_makefile(TESTFN) + self.assertEqual(vars, { + 'var1': 'ab42', + 'VAR2': 'b42', + 'var3': 42, + 'var4': '$/invalid', + 'var5': 'dollar$5', + }) def test_main(): - run_unittest(TestSysConfig) + run_unittest(TestSysConfig, MakefileTests) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -30,7 +30,7 @@ except Exception as e: errors.append(e.with_traceback(None)) finally: - done_tasks.append(thread.get_ident()) + done_tasks.append(threading.get_ident()) finished = len(done_tasks) == N if finished: done.set() diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -12,6 +12,7 @@ import weakref import os from test.script_helper import assert_python_ok, assert_python_failure +import subprocess from test import lock_tests @@ -172,7 +173,7 @@ exception = ctypes.py_object(AsyncExc) # First check it works when setting the exception from the same thread. - tid = _thread.get_ident() + tid = threading.get_ident() try: result = set_async_exc(ctypes.c_long(tid), exception) @@ -201,7 +202,7 @@ class Worker(threading.Thread): def run(self): - self.id = _thread.get_ident() + self.id = threading.get_ident() self.finished = False try: @@ -703,6 +704,37 @@ lock = threading.Lock() self.assertRaises(RuntimeError, lock.release) + @unittest.skipUnless(sys.platform == 'darwin', 'test macosx problem') + def test_recursion_limit(self): + # Issue 9670 + # test that excessive recursion within a non-main thread causes + # an exception rather than crashing the interpreter on platforms + # like Mac OS X or FreeBSD which have small default stack sizes + # for threads + script = """if True: + import threading + + def recurse(): + return recurse() + + def outer(): + try: + recurse() + except RuntimeError: + pass + + w = threading.Thread(target=outer) + w.start() + w.join() + print('end of main thread') + """ + expected_output = "end of main thread\n" + p = subprocess.Popen([sys.executable, "-c", script], + stdout=subprocess.PIPE) + stdout, stderr = p.communicate() + data = stdout.decode().replace('\r', '') + self.assertEqual(p.returncode, 0, "Unexpected error") + self.assertEqual(data, expected_output) class LockTests(lock_tests.LockTests): locktype = staticmethod(threading.Lock) diff --git a/Lib/threading.py b/Lib/threading.py --- a/Lib/threading.py +++ b/Lib/threading.py @@ -24,7 +24,7 @@ # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread _allocate_lock = _thread.allocate_lock -_get_ident = _thread.get_ident +get_ident = _thread.get_ident ThreadError = _thread.error try: _CRLock = _thread.RLock @@ -52,7 +52,7 @@ format = format % args # Issue #4188: calling current_thread() can incur an infinite # recursion if it has to create a DummyThread on the fly. - ident = _get_ident() + ident = get_ident() try: name = _active[ident].name except KeyError: @@ -110,7 +110,7 @@ self.__class__.__name__, owner, self._count) def acquire(self, blocking=True, timeout=-1): - me = _get_ident() + me = get_ident() if self._owner == me: self._count = self._count + 1 if __debug__: @@ -130,7 +130,7 @@ __enter__ = acquire def release(self): - if self._owner != _get_ident(): + if self._owner != get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: @@ -166,7 +166,7 @@ return (count, owner) def _is_owned(self): - return self._owner == _get_ident() + return self._owner == get_ident() _PyRLock = _RLock @@ -714,7 +714,7 @@ raise def _set_ident(self): - self._ident = _get_ident() + self._ident = get_ident() def _bootstrap_inner(self): try: @@ -787,7 +787,7 @@ try: # We don't call self._delete() because it also # grabs _active_limbo_lock. - del _active[_get_ident()] + del _active[get_ident()] except: pass @@ -823,7 +823,7 @@ try: with _active_limbo_lock: - del _active[_get_ident()] + del _active[get_ident()] # There must not be any python code between the previous line # and after the lock is released. Otherwise a tracing function # could try to acquire the lock again in the same thread, (in @@ -1006,9 +1006,8 @@ def current_thread(): try: - return _active[_get_ident()] + return _active[get_ident()] except KeyError: - ##print "current_thread(): no current thread for", _get_ident() return _DummyThread() currentThread = current_thread @@ -1062,7 +1061,7 @@ if thread is current: # There is only one active thread. We reset the ident to # its new value since it can have changed. - ident = _get_ident() + ident = get_ident() thread._ident = ident # Any condition variables hanging off of the active thread may # be in an invalid state, so we reinitialize them. diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -30,8 +30,6 @@ tk.mainloop() """ -__version__ = "$Revision$" - import sys if sys.platform == "win32": # Attempt to configure Tcl/Tk without requiring PATH diff --git a/Lib/wsgiref.egg-info b/Lib/wsgiref.egg-info deleted file mode 100644 --- a/Lib/wsgiref.egg-info +++ /dev/null @@ -1,8 +0,0 @@ -Metadata-Version: 1.0 -Name: wsgiref -Version: 0.1.2 -Summary: WSGI (PEP 333) Reference Library -Author: Phillip J. Eby -Author-email: web-sig at python.org -License: PSF or ZPL -Platform: UNKNOWN diff --git a/Lib/xml/parsers/expat.py b/Lib/xml/parsers/expat.py --- a/Lib/xml/parsers/expat.py +++ b/Lib/xml/parsers/expat.py @@ -1,6 +1,4 @@ """Interface to the Expat non-validating XML parser.""" -__version__ = '$Revision$' - import sys from pyexpat import * diff --git a/Mac/Makefile.in b/Mac/Makefile.in --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -76,6 +76,13 @@ do \ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done +ifneq ($(LIPO_32BIT_FLAGS),) + for fn in python3-32 pythonw3-32 \ + python$(VERSION)-32 pythonw$(VERSION)-32 ;\ + do \ + ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ + done +endif # @@ -90,6 +97,12 @@ do \ ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ done +ifneq ($(LIPO_32BIT_FLAGS),) + for fn in python$(VERSION)-32 pythonw$(VERSION)-32 ;\ + do \ + ln -fs "$(prefix)/bin/$${fn}" "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin/$${fn}" ;\ + done +endif pythonw: $(srcdir)/Tools/pythonw.c Makefile $(CC) $(LDFLAGS) -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' -o $@ $(srcdir)/Tools/pythonw.c -I.. -I$(srcdir)/../Include ../$(PYTHONFRAMEWORK).framework/Versions/$(VERSION)/$(PYTHONFRAMEWORK) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -274,7 +274,7 @@ ASDLGEN_FILES= $(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py # XXX Note that a build now requires Python exist before the build starts -ASDLGEN= $(srcdir)/Parser/asdl_c.py +ASDLGEN= @DISABLE_ASDLGEN@ $(srcdir)/Parser/asdl_c.py ########################################################################## # Python @@ -755,7 +755,7 @@ # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. -TESTOPTS= -l $(EXTRATESTOPTS) +TESTOPTS= -l --timeout=3600 $(EXTRATESTOPTS) TESTPROG= $(srcdir)/Lib/test/regrtest.py TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -Wd -E -bb $(TESTPYTHONOPTS) test: all platform @@ -888,6 +888,8 @@ (cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3) -rm -f $(DESTDIR)$(BINDIR)/2to3 (cd $(DESTDIR)$(BINDIR); $(LN) -s 2to3-$(VERSION) 2to3) + -rm -f $(DESTDIR)$(BINDIR)/pysetup3 + (cd $(DESTDIR)$(BINDIR); $(LN) -s pysetup$(VERSION) pysetup3) # Install the manual page maninstall: @@ -908,8 +910,8 @@ MACHDEPS= $(PLATDIR) $(EXTRAPLATDIR) XMLLIBSUBDIRS= xml xml/dom xml/etree xml/parsers xml/sax LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ - tkinter/test/test_ttk site-packages test \ - test/decimaltestdata test/xmltestdata test/subprocessdata \ + tkinter/test/test_ttk site-packages test \ + test/cjkencodings test/decimaltestdata test/xmltestdata test/subprocessdata \ test/tracedmodules test/encoded_modules \ collections concurrent concurrent/futures encodings \ email email/mime email/test email/test/data \ diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -12,7 +12,9 @@ and the list is in rough alphabetical order by last names. David Abrahams +Rajiv Abraham Ron Adam +Ali Afshar Jim Ahlstrom Farhan Ahmad Matthew Ahrens @@ -58,6 +60,7 @@ Cesar Eduardo Barros Des Barry Ulf Bartelt +Pior Bastida Nick Bastin Jeff Bauer Mike Bayer @@ -122,6 +125,7 @@ Daniel Brotsky Jean Brouwers Gary S. Brown +Titus Brown Oleg Broytmann Dave Brueck Stan Bubrouski @@ -135,6 +139,7 @@ Tarn Weisner Burton Lee Busby Ralph Butler +Nicolas Cadou Jp Calderone Daniel Calvelo Tony Campbell @@ -153,6 +158,7 @@ Mitch Chapman Greg Chapman Brad Chapman +Godefroid Chapelle David Chaum Nicolas Chauvat Jerry Chen @@ -176,6 +182,7 @@ Jeffery Collins Robert Collins Paul Colomiets +Christophe Combelles Denver Coneybeare Geremy Condra Juan Jos? Conti @@ -206,6 +213,7 @@ Lars Damerow Evan Dandrea Eric Daniel +Pierre-Yves David Scott David Daniels Ben Darnell Jonathan Dasteel @@ -213,6 +221,7 @@ Ned Deily Vincent Delft Arnaud Delobelle +Konrad Delong Erik Demaine Roger Dev Raghuram Devarakonda @@ -226,6 +235,7 @@ Humberto Diogenes Yves Dionne Daniel Dittmar +Josip Djolonga Jaromir Dolecek Ismail Donmez Marcos Donolo @@ -245,7 +255,6 @@ Andy Dustman Gary Duzan Eugene Dvurechenski -Josip Dzolonga Maxim Dzumanenko Walter D?rwald Hans Eckardt @@ -264,6 +273,7 @@ Michael Ernst Ben Escoto Andy Eskilsson +Andr? Espaze Stefan Esser Stephen D Evans Carey Evans @@ -277,8 +287,10 @@ Clovis Fabricio Andreas Faerber Bill Fancher +Andrew Francis Troy J. Farrell Mark Favas +Boris Feld Niels Ferguson Sebastian Fernandez Florian Festi @@ -328,6 +340,7 @@ Jonathan Giddy Johannes Gijsbers Michael Gilfix +Yannick Gingras Christoph Gohlke Tim Golden Chris Gonnerman @@ -351,6 +364,7 @@ Bob Halley Jesse Hallio Jun Hamano +Alexandre Hamelin Mark Hammond Manus Hand Milton L. Hankins @@ -382,6 +396,7 @@ Magnus L. Hetland Raymond Hettinger Kevan Heydon +Kelsey Hightower Jason Hildebrand Richie Hindle Konrad Hinsen @@ -409,6 +424,7 @@ Ken Howard Brad Howes Chih-Hao Huang +Christian Hudon Lawrence Hudson Michael Hudson Jim Hugunin @@ -417,6 +433,7 @@ Jeremy Hylton Gerhard H?ring Fredrik H??rd +Catalin Iacob Mihai Ibanescu Lars Immisch Bobby Impollonia @@ -435,6 +452,7 @@ Geert Jansen Jack Jansen Bill Janssen +Julien Jehannet Drew Jenkins Flemming Kj?r Jensen MunSic Jeong @@ -483,6 +501,7 @@ Bastian Kleineidam Bob Kline Matthias Klose +Jeremy Kloth Kim Knapp Lenny Kneler Pat Knight @@ -511,11 +530,13 @@ Andrew Langmead Detlef Lannert Soren Larsen +Amos Latteier Piers Lauder Ben Laurie Simon Law Chris Lawrence Brian Leair +Mathieu Leduc-Hamel James Lee John J. Lee Inyeol Lee @@ -531,6 +552,7 @@ Marc-Andre Lemburg John Lenton Christopher Tur Lesniewski-Laas +Alain Leufroy Mark Levinson William Lewis Xuanji Li @@ -575,6 +597,7 @@ S?bastien Martini Roger Masse Nick Mathewson +Simon Mathieu Graham Matthews Dieter Maurer Arnaud Mazin @@ -594,7 +617,9 @@ Ezio Melotti Brian Merrell Luke Mewburn +Carl Meyer Mike Meyer +Alexis M?taireau Steven Miale Trent Mick Stan Mihai @@ -604,20 +629,26 @@ Jason V. Miller Jay T. Miller Roman Milner +Julien Miotte Andrii V. Mishkovskyi Dustin J. Mitchell Dom Mitchell +Zubin Mithra Doug Moen The Dragon De Monsyne Skip Montanaro Paul Moore Derek Morr James A Morrison +Derek McTavish Mounce Pablo Mouzo +Mher Movsisyan Sjoerd Mullender Sape Mullender Michael Muller Neil Muller +Michael Mulich +Louis Munro R. David Murray Piotr Meyer John Nagle @@ -656,6 +687,7 @@ Jason Orendorff Douglas Orr Michele Orr? +Oleg Oshmyan Denis S. Otkidach Michael Otteneder R. M. Oudkerk @@ -670,11 +702,14 @@ Alexandre Parenteau Dan Parisien Harri Pasanen +Ga?l Pasgrimaud Randy Pausch Samuele Pedroni Marcel van der Peijl Steven Pemberton Santiago Peres?n +George Peristerakis +Mathieu Perreault Mark Perrego Trevor Perrin Gabriel de Perthuis @@ -683,6 +718,7 @@ Joe Peterson Chris Petrilli Bjorn Pettersen +Ronny Pfannschmidt Geoff Philbrick Gavrie Philipson Adrian Phillips @@ -710,6 +746,7 @@ Pierre Quentel Brian Quinlan Anders Qvist +J?r?me Radix Burton Radons Brodie Rao Antti Rasinen @@ -729,6 +766,7 @@ Bernhard Reiter Steven Reiz Roeland Rengelink +Antoine Reversat Tim Rice Francesco Ricciardi Jan Pieter Riegel @@ -743,11 +781,14 @@ Mark Roddy Kevin Rodgers Giampaolo Rodola +Luis Rojas Mike Romberg Armin Ronacher Case Roole Timothy Roscoe +Erik Rose Jim Roskind +Brian Rosner Just van Rossum Hugo van Rossum Saskia van Rossum diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,37 @@ Core and Builtins ----------------- +- Issue #12225: Still allow Python to build if Python is not in its hg repo or + mercurial is not installed. + +- Issue #1195: my_fgets() now always clears errors before calling fgets(). Fix + the following case: sys.stdin.read() stopped with CTRL+d (end of file), + raw_input() interrupted by CTRL+c. + +- Issue #12216: Allow unexpected EOF errors to happen on any line of the file. + +- Issue #12199: The TryExcept and TryFinally and AST nodes have been unified + into a Try node. + +- Issue #9670: Increase the default stack size for secondary threads on + Mac OS X and FreeBSD to reduce the chances of a crash instead of a + "maximum recursion depth" RuntimeError exception. + (patch by Ronald Oussoren) + +- Issue #12106: The use of the multiple-with shorthand syntax is now reflected + in the AST. + +- Issue #12190: Try to use the same filename object when compiling unmarshalling + a code objects in the same file. + +- Issue #12166: Move implementations of dir() specialized for various types into + the __dir__() methods of those types. + +- Issue #5715: In socketserver, close the server socket in the child process. + +- Correct lookup of __dir__ on objects. Among other things, this causes errors + besides AttributeError found on lookup to be propagated. + - Issue #12060: Use sig_atomic_t type and volatile keyword in the signal module. Patch written by Charles-Fran?ois Natali. @@ -88,7 +119,7 @@ - Issue #11320: fix bogus memory management in Modules/getpath.c, leading to a possible crash when calling Py_SetPath(). -- _ast.__version__ is now a Mercurial integer and hex revision. +- _ast.__version__ is now a Mercurial hex revision. - Issue #11432: A bug was introduced in subprocess.Popen on posix systems with 3.2.0 where the stdout or stderr file descriptor being the same as the stdin @@ -153,6 +184,74 @@ Library ------- +- Issue #12080: Fix a Decimal.power() case that took an unreasonably long time + to compute. + +- Issue #12221: Remove __version__ attributes from pyexpat, pickle, tarfile, + pydoc, tkinter, and xml.parsers.expat. This were useless version constants + left over from the Mercurial transition + +- Named tuples now work correctly with vars(). + +- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the + constructor has failed, e.g. because of an undeclared keyword argument. Patch + written by Oleg Oshmyan. + +- Issue #12028: Make threading._get_ident() public, rename it to + threading.get_ident() and document it. This function was already used using + _thread.get_ident(). + +- Issue #12171: IncrementalEncoder.reset() of CJK codecs (multibytecodec) calls + encreset() instead of decreset(). + +- Issue #12218: Removed wsgiref.egg-info. + +- Issue #12196: Add pipe2() to the os module. + +- Issue #985064: Make plistlib more resilient to faulty input plists. + Patch by Mher Movsisyan. + +- Issue #1625: BZ2File and bz2.decompress() now support multi-stream files. + Initial patch by Nir Aides. + +- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available. + +- Issue #12175: FileIO.readall() now only reads the file position and size + once. + +- Issue #12175: RawIOBase.readall() now returns None if read() returns None. + +- Issue #12175: FileIO.readall() now raises a ValueError instead of an IOError + if the file is closed. + +- Issue #11109: New service_action method for BaseServer, used by ForkingMixin + class for cleanup. Initial Patch by Justin Wark. + +- Issue #12045: Avoid duplicate execution of command in + ctypes.util._get_soname(). Patch by Sijin Joseph. + +- Issue #10818: Remove the Tk GUI and the serve() function of the pydoc module, + pydoc -g has been deprecated in Python 3.2 and it has a new enhanced web + server. + +- Issue #1441530: In imaplib, read the data in one chunk to speed up large + reads and simplify code. + +- Issue #12070: Fix the Makefile parser of the sysconfig module to handle + correctly references to "bogus variable" (e.g. "prefix=$/opt/python"). + +- Issue #12100: Don't reset incremental encoders of CJK codecs at each call to + their encode() method anymore, but continue to call the reset() method if the + final argument is True. + +- Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl + module. + +- Issue #12125: fixed the failures under Solaris due to improper test cleanup. + +- Issue #6501: os.device_encoding() returns None on Windows if the application + has no console. + - Issue #12132: Skip test_build_ext in case the xxmodule is not found. - Issue #12105: Add O_CLOEXEC to the os module. @@ -164,8 +263,8 @@ - Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore to be able to unload the module. -- Issue #12120, #12119: skip a test in packaging and distutils - if sys.dont_write_bytecode is set to True. +- Add the packaging module, an improved fork of distutils (also known as + distutils2). - Issue #12065: connect_ex() on an SSL socket now returns the original errno when the socket's timeout expires (it used to return None). @@ -379,11 +478,12 @@ - Issue #7311: fix html.parser to accept non-ASCII attribute values. -- Issue #11605: email.parser.BytesFeedParser was incorrectly converting multipart - subpararts with an 8bit CTE into unicode instead of preserving the bytes. - -- Issue #1690608: email.util.formataddr is now RFC2047 aware: it now has a - charset parameter that defaults utf-8 which is used as the charset for RFC +- Issue #11605: email.parser.BytesFeedParser was incorrectly converting + multipart subparts with an 8-bit CTE into unicode instead of preserving the + bytes. + +- Issue #1690608: email.util.formataddr is now RFC 2047 aware: it now has a + charset parameter that defaults to utf-8 and is used as the charset for RFC 2047 encoding when the realname contains non-ASCII characters. - Issue #10963: Ensure that subprocess.communicate() never raises EPIPE. @@ -537,7 +637,7 @@ the "n" as the flag argument and the file exists. The behavior matches the documentation and general logic. -- Issue #1162477: Postel Principal adjustment to email date parsing: handle the +- Issue #1162477: Postel Principle adjustment to email date parsing: handle the fact that some non-compliant MUAs use '.' instead of ':' in time specs. - Issue #11131: Fix sign of zero in decimal.Decimal plus and minus @@ -661,6 +761,10 @@ Build ----- +- Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, + ensure "make install" creates symlinks in --prefix bin for the "-32" + files in the framework bin directory like the installer does. + - Issue #11347: Use --no-as-needed when linking libpython3.so. - Issue #11411: Fix 'make DESTDIR=' with a relative destination. @@ -688,6 +792,8 @@ Extension Modules ----------------- +- Issue #12221: Replace pyexpat.__version__ with the Python version. + - Issue #12051: Fix segfault in json.dumps() while encoding highly-nested objects using the C accelerations. @@ -700,6 +806,15 @@ Tests ----- +- Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, + iso2022_kr). + +- Issue #12180: Fixed a few remaining errors in test_packaging when no + threading. + +- Issue #12120, #12119: skip a test in packaging and distutils + if sys.dont_write_bytecode is set to True. + - Issue #12096: Fix a race condition in test_threading.test_waitfor(). Patch written by Charles-Fran?ois Natali. @@ -754,12 +869,12 @@ - New test_crashers added to exercise the scripts in the Lib/test/crashers directory and confirm they fail as expected -- Issue #11578: added test for the timeit module. Patch Michael Henry. +- Issue #11578: added test for the timeit module. Patch by Michael Henry. - Issue #11503: improve test coverage of posixpath.py. Patch by Evan Dandrea. -- Issue #11505: improves test coverage of string.py. Patch by Alicia - Arlen. +- Issue #11505: improves test coverage of string.py, increases granularity of + string.Formatter tests. Initial patch by Alicia Arlen. - Issue #11548: Improve test coverage of the shutil module. Patch by Evan Dandrea. @@ -793,7 +908,11 @@ C-API ----- -- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with Mercurial. +- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with + Mercurial. + +- Issue #12173: The first argument of PyImport_ImportModuleLevel is now `const + char *` instead of `char *`. Documentation ------------- @@ -1064,10 +1183,10 @@ comparisons that could lead to infinite recursion. - Issue #10686: the email package now :rfc:`2047`\ -encodes headers with - non-ASCII bytes (parsed by a Bytes Parser) when doing conversion to 7bit-clean + non-ASCII bytes (parsed by a BytesParser) when doing conversion to 7bit-clean presentation, instead of replacing them with ?s. -- email.header.Header was incorrectly encoding folding white space when +- email.header.Header was incorrectly encoding folding whitespace when rfc2047-encoding header values with embedded newlines, leaving them without folding whitespace. It now uses the continuation_ws, as it does for continuation lines that it creates itself. diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -36,6 +36,7 @@ PyObject *_PyIO_str_read; PyObject *_PyIO_str_read1; PyObject *_PyIO_str_readable; +PyObject *_PyIO_str_readall; PyObject *_PyIO_str_readinto; PyObject *_PyIO_str_readline; PyObject *_PyIO_str_reset; @@ -767,6 +768,8 @@ goto fail; if (!(_PyIO_str_readable = PyUnicode_InternFromString("readable"))) goto fail; + if (!(_PyIO_str_readall = PyUnicode_InternFromString("readall"))) + goto fail; if (!(_PyIO_str_readinto = PyUnicode_InternFromString("readinto"))) goto fail; if (!(_PyIO_str_readline = PyUnicode_InternFromString("readline"))) diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -155,6 +155,7 @@ extern PyObject *_PyIO_str_read; extern PyObject *_PyIO_str_read1; extern PyObject *_PyIO_str_readable; +extern PyObject *_PyIO_str_readall; extern PyObject *_PyIO_str_readinto; extern PyObject *_PyIO_str_readline; extern PyObject *_PyIO_str_reset; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -589,7 +589,7 @@ static void _bufferedwriter_reset_buf(buffered *self); static PyObject * -_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t); +_bufferedreader_peek_unlocked(buffered *self); static PyObject * _bufferedreader_read_all(buffered *self); static PyObject * @@ -797,7 +797,7 @@ goto end; Py_CLEAR(res); } - res = _bufferedreader_peek_unlocked(self, n); + res = _bufferedreader_peek_unlocked(self); end: LEAVE_BUFFERED(self) @@ -1407,32 +1407,57 @@ _bufferedreader_read_all(buffered *self) { Py_ssize_t current_size; - PyObject *res, *data = NULL; - PyObject *chunks = PyList_New(0); - - if (chunks == NULL) - return NULL; + PyObject *res, *data = NULL, *chunk, *chunks; /* First copy what we have in the current buffer. */ current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (current_size) { data = PyBytes_FromStringAndSize( self->buffer + self->pos, current_size); - if (data == NULL) { - Py_DECREF(chunks); + if (data == NULL) return NULL; - } } _bufferedreader_reset_buf(self); /* We're going past the buffer's bounds, flush it */ if (self->writable) { res = _bufferedwriter_flush_unlocked(self, 1); - if (res == NULL) { - Py_DECREF(chunks); + if (res == NULL) + return NULL; + Py_CLEAR(res); + } + + if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) { + chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL); + if (chunk == NULL) + return NULL; + if (chunk != Py_None && !PyBytes_Check(chunk)) { + Py_XDECREF(data); + Py_DECREF(chunk); + PyErr_SetString(PyExc_TypeError, "readall() should return bytes"); return NULL; } - Py_CLEAR(res); + if (chunk == Py_None) { + if (current_size == 0) + return chunk; + else { + Py_DECREF(chunk); + return data; + } + } + else if (current_size) { + PyBytes_Concat(&data, chunk); + Py_DECREF(chunk); + if (data == NULL) + return NULL; + return data; + } else + return chunk; } + + chunks = PyList_New(0); + if (chunks == NULL) + return NULL; + while (1) { if (data) { if (PyList_Append(chunks, data) < 0) { @@ -1586,7 +1611,7 @@ } static PyObject * -_bufferedreader_peek_unlocked(buffered *self, Py_ssize_t n) +_bufferedreader_peek_unlocked(buffered *self) { Py_ssize_t have, r; diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -547,14 +547,14 @@ } static size_t -new_buffersize(fileio *self, size_t currentsize) +new_buffersize(fileio *self, size_t currentsize +#ifdef HAVE_FSTAT + , off_t pos, off_t end +#endif + ) { #ifdef HAVE_FSTAT - off_t pos, end; - struct stat st; - if (fstat(self->fd, &st) == 0) { - end = st.st_size; - pos = lseek(self->fd, 0L, SEEK_CUR); + if (end != (off_t)-1) { /* Files claiming a size smaller than SMALLCHUNK may actually be streaming pseudo-files. In this case, we apply the more aggressive algorithm below. @@ -579,10 +579,17 @@ static PyObject * fileio_readall(fileio *self) { +#ifdef HAVE_FSTAT + struct stat st; + off_t pos, end; +#endif PyObject *result; Py_ssize_t total = 0; int n; + size_t newsize; + if (self->fd < 0) + return err_closed(); if (!_PyVerify_fd(self->fd)) return PyErr_SetFromErrno(PyExc_IOError); @@ -590,8 +597,23 @@ if (result == NULL) return NULL; +#ifdef HAVE_FSTAT +#if defined(MS_WIN64) || defined(MS_WINDOWS) + pos = _lseeki64(self->fd, 0L, SEEK_CUR); +#else + pos = lseek(self->fd, 0L, SEEK_CUR); +#endif + if (fstat(self->fd, &st) == 0) + end = st.st_size; + else + end = (off_t)-1; +#endif while (1) { - size_t newsize = new_buffersize(self, total); +#ifdef HAVE_FSTAT + newsize = new_buffersize(self, total, pos, end); +#else + newsize = new_buffersize(self, total); +#endif if (newsize > PY_SSIZE_T_MAX || newsize <= 0) { PyErr_SetString(PyExc_OverflowError, "unbounded read returned more bytes " @@ -630,6 +652,9 @@ return NULL; } total += n; +#ifdef HAVE_FSTAT + pos += n; +#endif } if (PyBytes_GET_SIZE(result) > total) { diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -815,6 +815,14 @@ Py_DECREF(chunks); return NULL; } + if (data == Py_None) { + if (PyList_GET_SIZE(chunks) == 0) { + Py_DECREF(chunks); + return data; + } + Py_DECREF(data); + break; + } if (!PyBytes_Check(data)) { Py_DECREF(chunks); Py_DECREF(data); diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1513,8 +1513,13 @@ PyObject *decoded; if (bytes == NULL) goto fail; - decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, - bytes, Py_True, NULL); + + if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) + decoded = _PyIncrementalNewlineDecoder_decode(self->decoder, + bytes, 1); + else + decoded = PyObject_CallMethodObjArgs( + self->decoder, _PyIO_str_decode, bytes, Py_True, NULL); Py_DECREF(bytes); if (decoded == NULL) goto fail; diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -1,7 +1,7 @@ /* Authors: Gregory P. Smith & Jeffrey Yasskin */ #include "Python.h" -#ifdef HAVE_PIPE2 -#define _GNU_SOURCE +#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE #endif #include #include diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -200,11 +200,13 @@ weakref = PyList_GetItem(self->statements, i); statement = PyWeakref_GetObject(weakref); if (statement != Py_None) { + Py_INCREF(statement); if (action == ACTION_RESET) { (void)pysqlite_statement_reset((pysqlite_Statement*)statement); } else { (void)pysqlite_statement_finalize((pysqlite_Statement*)statement); } + Py_DECREF(statement); } } diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1887,6 +1887,69 @@ bound on the entropy contained in string. See RFC 1750."); static PyObject * +PySSL_RAND(int len, int pseudo) +{ + int ok; + PyObject *bytes; + unsigned long err; + const char *errstr; + PyObject *v; + + bytes = PyBytes_FromStringAndSize(NULL, len); + if (bytes == NULL) + return NULL; + if (pseudo) { + ok = RAND_pseudo_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); + if (ok == 0 || ok == 1) + return Py_BuildValue("NO", bytes, ok == 1 ? Py_True : Py_False); + } + else { + ok = RAND_bytes((unsigned char*)PyBytes_AS_STRING(bytes), len); + if (ok == 1) + return bytes; + } + Py_DECREF(bytes); + + err = ERR_get_error(); + errstr = ERR_reason_error_string(err); + v = Py_BuildValue("(ks)", err, errstr); + if (v != NULL) { + PyErr_SetObject(PySSLErrorObject, v); + Py_DECREF(v); + } + return NULL; +} + +static PyObject * +PySSL_RAND_bytes(PyObject *self, PyObject *args) +{ + int len; + if (!PyArg_ParseTuple(args, "i:RAND_bytes", &len)) + return NULL; + return PySSL_RAND(len, 0); +} + +PyDoc_STRVAR(PySSL_RAND_bytes_doc, +"RAND_bytes(n) -> bytes\n\ +\n\ +Generate n cryptographically strong pseudo-random bytes."); + +static PyObject * +PySSL_RAND_pseudo_bytes(PyObject *self, PyObject *args) +{ + int len; + if (!PyArg_ParseTuple(args, "i:RAND_pseudo_bytes", &len)) + return NULL; + return PySSL_RAND(len, 1); +} + +PyDoc_STRVAR(PySSL_RAND_pseudo_bytes_doc, +"RAND_pseudo_bytes(n) -> (bytes, is_cryptographic)\n\ +\n\ +Generate n pseudo-random bytes. is_cryptographic is True if the bytes\ +generated are cryptographically strong."); + +static PyObject * PySSL_RAND_status(PyObject *self) { return PyLong_FromLong(RAND_status()); @@ -1939,6 +2002,10 @@ #ifdef HAVE_OPENSSL_RAND {"RAND_add", PySSL_RAND_add, METH_VARARGS, PySSL_RAND_add_doc}, + {"RAND_bytes", PySSL_RAND_bytes, METH_VARARGS, + PySSL_RAND_bytes_doc}, + {"RAND_pseudo_bytes", PySSL_RAND_pseudo_bytes, METH_VARARGS, + PySSL_RAND_pseudo_bytes_doc}, {"RAND_egd", PySSL_RAND_egd, METH_VARARGS, PySSL_RAND_egd_doc}, {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -1098,7 +1098,7 @@ PyDoc_STRVAR(exit_doc, "exit()\n\ -(PyThread_exit_thread() is an obsolete synonym)\n\ +(exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught."); diff --git a/Modules/cjkcodecs/_codecs_hk.c b/Modules/cjkcodecs/_codecs_hk.c --- a/Modules/cjkcodecs/_codecs_hk.c +++ b/Modules/cjkcodecs/_codecs_hk.c @@ -115,55 +115,56 @@ REQUIRE_INBUF(2) - if (0xc6 <= c && c <= 0xc8 && (c >= 0xc7 || IN2 >= 0xa1)) - goto hkscsdec; + if (0xc6 > c || c > 0xc8 || (c < 0xc7 && IN2 < 0xa1)) { + TRYMAP_DEC(big5, **outbuf, c, IN2) { + NEXT(2, 1) + continue; + } + } - TRYMAP_DEC(big5, **outbuf, c, IN2) { - NEXT(2, 1) + TRYMAP_DEC(big5hkscs, decoded, c, IN2) + { + int s = BH2S(c, IN2); + const unsigned char *hintbase; + + assert(0x87 <= c && c <= 0xfe); + assert(0x40 <= IN2 && IN2 <= 0xfe); + + if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) { + hintbase = big5hkscs_phint_0; + s -= BH2S(0x87, 0x40); + } + else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){ + hintbase = big5hkscs_phint_12130; + s -= BH2S(0xc6, 0xa1); + } + else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){ + hintbase = big5hkscs_phint_21924; + s -= BH2S(0xf9, 0xd6); + } + else + return MBERR_INTERNAL; + + if (hintbase[s >> 3] & (1 << (s & 7))) { + WRITEUCS4(decoded | 0x20000) + NEXT_IN(2) + } + else { + OUT1(decoded) + NEXT(2, 1) + } + continue; } - else -hkscsdec: TRYMAP_DEC(big5hkscs, decoded, c, IN2) { - int s = BH2S(c, IN2); - const unsigned char *hintbase; - assert(0x87 <= c && c <= 0xfe); - assert(0x40 <= IN2 && IN2 <= 0xfe); + switch ((c << 8) | IN2) { + case 0x8862: WRITE2(0x00ca, 0x0304); break; + case 0x8864: WRITE2(0x00ca, 0x030c); break; + case 0x88a3: WRITE2(0x00ea, 0x0304); break; + case 0x88a5: WRITE2(0x00ea, 0x030c); break; + default: return 2; + } - if (BH2S(0x87, 0x40) <= s && s <= BH2S(0xa0, 0xfe)) { - hintbase = big5hkscs_phint_0; - s -= BH2S(0x87, 0x40); - } - else if (BH2S(0xc6,0xa1) <= s && s <= BH2S(0xc8,0xfe)){ - hintbase = big5hkscs_phint_12130; - s -= BH2S(0xc6, 0xa1); - } - else if (BH2S(0xf9,0xd6) <= s && s <= BH2S(0xfe,0xfe)){ - hintbase = big5hkscs_phint_21924; - s -= BH2S(0xf9, 0xd6); - } - else - return MBERR_INTERNAL; - - if (hintbase[s >> 3] & (1 << (s & 7))) { - WRITEUCS4(decoded | 0x20000) - NEXT_IN(2) - } - else { - OUT1(decoded) - NEXT(2, 1) - } - } - else { - switch ((c << 8) | IN2) { - case 0x8862: WRITE2(0x00ca, 0x0304); break; - case 0x8864: WRITE2(0x00ca, 0x030c); break; - case 0x88a3: WRITE2(0x00ea, 0x0304); break; - case 0x88a5: WRITE2(0x00ea, 0x030c); break; - default: return 2; - } - - NEXT(2, 2) /* all decoded codepoints are pairs, above. */ - } + NEXT(2, 2) /* all decoded codepoints are pairs, above. */ } return 0; diff --git a/Modules/cjkcodecs/_codecs_jp.c b/Modules/cjkcodecs/_codecs_jp.c --- a/Modules/cjkcodecs/_codecs_jp.c +++ b/Modules/cjkcodecs/_codecs_jp.c @@ -371,11 +371,11 @@ REQUIRE_OUTBUF(1) - if (c < 0x80) { - OUT1(c) - NEXT(1, 1) - continue; - } + if (c < 0x80) { + OUT1(c) + NEXT(1, 1) + continue; + } if (c == 0x8e) { /* JIS X 0201 half-width katakana */ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -479,7 +479,7 @@ MultibyteEncodeBuffer buf; Py_ssize_t finalsize, r = 0; - if (datalen == 0) + if (datalen == 0 && !(flags & MBENC_RESET)) return PyBytes_FromStringAndSize(NULL, 0); buf.excobj = NULL; @@ -515,7 +515,7 @@ break; } - if (codec->encreset != NULL) + if (codec->encreset != NULL && (flags & MBENC_RESET)) for (;;) { Py_ssize_t outleft; @@ -785,8 +785,8 @@ inbuf_end = inbuf + datalen; r = multibytecodec_encode(ctx->codec, &ctx->state, - (const Py_UNICODE **)&inbuf, - datalen, ctx->errors, final ? MBENC_FLUSH : 0); + (const Py_UNICODE **)&inbuf, datalen, + ctx->errors, final ? MBENC_FLUSH | MBENC_RESET : 0); if (r == NULL) { /* recover the original pending buffer */ if (origpending > 0) @@ -901,11 +901,17 @@ static PyObject * mbiencoder_reset(MultibyteIncrementalEncoderObject *self) { - if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) - return NULL; + /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ + unsigned char buffer[4], *outbuf; + Py_ssize_t r; + if (self->codec->encreset != NULL) { + outbuf = buffer; + r = self->codec->encreset(&self->state, self->codec->config, + &outbuf, sizeof(buffer)); + if (r != 0) + return NULL; + } self->pendingsize = 0; - Py_RETURN_NONE; } diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -854,7 +854,7 @@ } #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -void* +static void* stack_overflow(void *min_sp, void *max_sp, size_t *depth) { /* allocate 4096 bytes on the stack at each call */ @@ -1005,9 +1005,10 @@ faulthandler_env_options(void) { PyObject *xoptions, *key, *module, *res; - int enable; if (!Py_GETENV("PYTHONFAULTHANDLER")) { + int has_key; + xoptions = PySys_GetXOptions(); if (xoptions == NULL) return -1; @@ -1016,13 +1017,11 @@ if (key == NULL) return -1; - enable = PyDict_Contains(xoptions, key); + has_key = PyDict_Contains(xoptions, key); Py_DECREF(key); - if (!enable) + if (!has_key) return 0; } - else - enable = 1; module = PyImport_ImportModule("faulthandler"); if (module == NULL) { diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -581,10 +581,11 @@ if (res) ((PyST_Object *)res)->st_flags.cf_flags = flags & PyCF_MASK; } - else + else { PyParser_SetError(&err); + PyParser_ClearError(&err); + } } - PyParser_ClearError(&err); return (res); } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6547,6 +6547,31 @@ } #endif /* HAVE_PIPE */ +#ifdef HAVE_PIPE2 +PyDoc_STRVAR(posix_pipe2__doc__, +"pipe2(flags=0) -> (read_end, write_end)\n\n\ +Create a pipe with flags set atomically.\ +flags is optional and can be constructed by ORing together zero or more\n\ +of these values: O_NONBLOCK, O_CLOEXEC.\n\ +"); + +static PyObject * +posix_pipe2(PyObject *self, PyObject *args) +{ + int flags = 0; + int fds[2]; + int res; + + if (!PyArg_ParseTuple(args, "|i:pipe2", &flags)) + return NULL; + + res = pipe2(fds, flags); + if (res != 0) + return posix_error(); + return Py_BuildValue("(ii)", fds[0], fds[1]); +} +#endif /* HAVE_PIPE2 */ + #ifdef HAVE_WRITEV PyDoc_STRVAR(posix_writev__doc__, "writev(fd, buffers) -> byteswritten\n\n\ @@ -8495,6 +8520,9 @@ device_encoding(PyObject *self, PyObject *args) { int fd; +#if defined(MS_WINDOWS) || defined(MS_WIN64) + UINT cp; +#endif if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) return NULL; if (!_PyVerify_fd(fd) || !isatty(fd)) { @@ -8502,16 +8530,16 @@ return Py_None; } #if defined(MS_WINDOWS) || defined(MS_WIN64) - if (fd == 0) { - char buf[100]; - sprintf(buf, "cp%d", GetConsoleCP()); - return PyUnicode_FromString(buf); - } - if (fd == 1 || fd == 2) { - char buf[100]; - sprintf(buf, "cp%d", GetConsoleOutputCP()); - return PyUnicode_FromString(buf); - } + if (fd == 0) + cp = GetConsoleCP(); + else if (fd == 1 || fd == 2) + cp = GetConsoleOutputCP(); + else + cp = 0; + /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application + has no console */ + if (cp != 0) + return PyUnicode_FromFormat("cp%u", (unsigned int)cp); #elif defined(CODESET) { char *codeset = nl_langinfo(CODESET); @@ -9438,6 +9466,9 @@ #ifdef HAVE_PIPE {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, #endif +#ifdef HAVE_PIPE2 + {"pipe2", posix_pipe2, METH_VARARGS, posix_pipe2__doc__}, +#endif #ifdef HAVE_MKFIFO {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, #endif diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1622,26 +1622,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, "Python wrapper for Expat parser."); -/* Return a Python string that represents the version number without the - * extra cruft added by revision control, even if the right options were - * given to the "cvs export" command to make it not include the extra - * cruft. - */ -static PyObject * -get_version_string(void) -{ - static char *rcsid = "$Revision$"; - char *rev = rcsid; - int i = 0; - - while (!isdigit(Py_CHARMASK(*rev))) - ++rev; - while (rev[i] != ' ' && rev[i] != '\0') - ++i; - - return PyUnicode_FromStringAndSize(rev, i); -} - /* Initialization function for the module */ #ifndef MODULE_NAME @@ -1718,7 +1698,6 @@ Py_INCREF(&Xmlparsetype); PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); - PyModule_AddObject(m, "__version__", get_version_string()); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion()); { diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -177,17 +177,18 @@ trip_signal(int sig_num) { unsigned char byte; + Handlers[sig_num].tripped = 1; + if (wakeup_fd != -1) { + byte = (unsigned char)sig_num; + write(wakeup_fd, &byte, 1); + } if (is_tripped) return; /* Set is_tripped after setting .tripped, as it gets cleared in PyErr_CheckSignals() before .tripped. */ is_tripped = 1; Py_AddPendingCall(checksignals_witharg, NULL); - if (wakeup_fd != -1) { - byte = (unsigned char)sig_num; - write(wakeup_fd, &byte, 1); - } } static void diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2782,6 +2782,7 @@ PyErr_Format(PyExc_TypeError, "sendto() takes 2 or 3 arguments (%d given)", arglen); + return NULL; } if (PyErr_Occurred()) return NULL; @@ -3144,7 +3145,7 @@ } return PyErr_SetExcFromWindowsErr(PyExc_WindowsError, GetLastError()); } - return PyUnicode_FromUnicode(buf, size); + return PyUnicode_FromUnicode(buf, size); #else char buf[1024]; int res; @@ -4038,7 +4039,7 @@ static PyObject * socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) { - static char* kwnames[] = {"host", "port", "family", "type", "proto", + static char* kwnames[] = {"host", "port", "family", "type", "proto", "flags", 0}; struct addrinfo hints, *res; struct addrinfo *res0 = NULL; @@ -4053,7 +4054,7 @@ family = socktype = protocol = flags = 0; family = AF_UNSPEC; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iiii:getaddrinfo", kwnames, &hobj, &pobj, &family, &socktype, &protocol, &flags)) { return NULL; @@ -4289,7 +4290,7 @@ PyObject *list; int i; struct if_nameindex *ni; - + ni = if_nameindex(); if (ni == NULL) { PyErr_SetFromErrno(socket_error); diff --git a/Modules/zipimport.c b/Modules/zipimport.c --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -1196,7 +1196,7 @@ int *p_ispackage, PyObject **p_modpath) { PyObject *code = NULL, *toc_entry, *subname; - PyObject *path, *fullpath; + PyObject *path, *fullpath = NULL; struct st_zip_searchorder *zso; subname = get_subname(fullname); diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -237,7 +237,8 @@ pb = obj->ob_type->tp_as_buffer; if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_SetString(PyExc_TypeError, - "expected an object with the buffer interface"); + "expected bytes, bytearray " + "or buffer compatible object"); return -1; } if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -499,7 +499,7 @@ Py_CLEAR(self->code); if (size == 1) self->code = PyTuple_GET_ITEM(args, 0); - else if (size > 1) + else /* size > 1 */ self->code = args; Py_INCREF(self->code); return 0; diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -413,6 +413,34 @@ return 0; } +static PyObject * +module_dir(PyObject *self, PyObject *args) +{ + PyObject *result = NULL; + PyObject *dict = PyObject_GetAttrString(self, "__dict__"); + + if (dict != NULL) { + if (PyDict_Check(dict)) + result = PyDict_Keys(dict); + else { + const char *name = PyModule_GetName(self); + if (name) + PyErr_Format(PyExc_TypeError, + "%.200s.__dict__ is not a dictionary", + name); + } + } + + Py_XDECREF(dict); + return result; +} + +static PyMethodDef module_methods[] = { + {"__dir__", module_dir, METH_NOARGS, + PyDoc_STR("__dir__() -> list\nspecialized dir() implementation")}, + {0} +}; + PyDoc_STRVAR(module_doc, "module(name[, doc])\n\ @@ -449,7 +477,7 @@ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + module_methods, /* tp_methods */ module_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ diff --git a/Objects/object.c b/Objects/object.c --- a/Objects/object.c +++ b/Objects/object.c @@ -1182,66 +1182,6 @@ return x->ob_type->tp_call != NULL; } -/* ------------------------- PyObject_Dir() helpers ------------------------- */ - -/* Helper for PyObject_Dir. - Merge the __dict__ of aclass into dict, and recursively also all - the __dict__s of aclass's base classes. The order of merging isn't - defined, as it's expected that only the final set of dict keys is - interesting. - Return 0 on success, -1 on error. -*/ - -static int -merge_class_dict(PyObject* dict, PyObject* aclass) -{ - PyObject *classdict; - PyObject *bases; - - assert(PyDict_Check(dict)); - assert(aclass); - - /* Merge in the type's dict (if any). */ - classdict = PyObject_GetAttrString(aclass, "__dict__"); - if (classdict == NULL) - PyErr_Clear(); - else { - int status = PyDict_Update(dict, classdict); - Py_DECREF(classdict); - if (status < 0) - return -1; - } - - /* Recursively merge in the base types' (if any) dicts. */ - bases = PyObject_GetAttrString(aclass, "__bases__"); - if (bases == NULL) - PyErr_Clear(); - else { - /* We have no guarantee that bases is a real tuple */ - Py_ssize_t i, n; - n = PySequence_Size(bases); /* This better be right */ - if (n < 0) - PyErr_Clear(); - else { - for (i = 0; i < n; i++) { - int status; - PyObject *base = PySequence_GetItem(bases, i); - if (base == NULL) { - Py_DECREF(bases); - return -1; - } - status = merge_class_dict(dict, base); - Py_DECREF(base); - if (status < 0) { - Py_DECREF(bases); - return -1; - } - } - } - Py_DECREF(bases); - } - return 0; -} /* Helper for PyObject_Dir without arguments: returns the local scope. */ static PyObject * @@ -1269,132 +1209,34 @@ return names; } -/* Helper for PyObject_Dir of type objects: returns __dict__ and __bases__. - We deliberately don't suck up its __class__, as methods belonging to the - metaclass would probably be more confusing than helpful. -*/ -static PyObject * -_specialized_dir_type(PyObject *obj) -{ - PyObject *result = NULL; - PyObject *dict = PyDict_New(); - - if (dict != NULL && merge_class_dict(dict, obj) == 0) - result = PyDict_Keys(dict); - - Py_XDECREF(dict); - return result; -} - -/* Helper for PyObject_Dir of module objects: returns the module's __dict__. */ -static PyObject * -_specialized_dir_module(PyObject *obj) -{ - PyObject *result = NULL; - PyObject *dict = PyObject_GetAttrString(obj, "__dict__"); - - if (dict != NULL) { - if (PyDict_Check(dict)) - result = PyDict_Keys(dict); - else { - const char *name = PyModule_GetName(obj); - if (name) - PyErr_Format(PyExc_TypeError, - "%.200s.__dict__ is not a dictionary", - name); - } - } - - Py_XDECREF(dict); - return result; -} - -/* Helper for PyObject_Dir of generic objects: returns __dict__, __class__, - and recursively up the __class__.__bases__ chain. -*/ -static PyObject * -_generic_dir(PyObject *obj) -{ - PyObject *result = NULL; - PyObject *dict = NULL; - PyObject *itsclass = NULL; - - /* Get __dict__ (which may or may not be a real dict...) */ - dict = PyObject_GetAttrString(obj, "__dict__"); - if (dict == NULL) { - PyErr_Clear(); - dict = PyDict_New(); - } - else if (!PyDict_Check(dict)) { - Py_DECREF(dict); - dict = PyDict_New(); - } - else { - /* Copy __dict__ to avoid mutating it. */ - PyObject *temp = PyDict_Copy(dict); - Py_DECREF(dict); - dict = temp; - } - - if (dict == NULL) - goto error; - - /* Merge in attrs reachable from its class. */ - itsclass = PyObject_GetAttrString(obj, "__class__"); - if (itsclass == NULL) - /* XXX(tomer): Perhaps fall back to obj->ob_type if no - __class__ exists? */ - PyErr_Clear(); - else { - if (merge_class_dict(dict, itsclass) != 0) - goto error; - } - - result = PyDict_Keys(dict); - /* fall through */ -error: - Py_XDECREF(itsclass); - Py_XDECREF(dict); - return result; -} - -/* Helper for PyObject_Dir: object introspection. - This calls one of the above specialized versions if no __dir__ method - exists. */ +/* Helper for PyObject_Dir: object introspection. */ static PyObject * _dir_object(PyObject *obj) { - PyObject * result = NULL; - PyObject * dirfunc = PyObject_GetAttrString((PyObject*)obj->ob_type, - "__dir__"); + PyObject *result; + static PyObject *dir_str = NULL; + PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str); assert(obj); if (dirfunc == NULL) { - /* use default implementation */ - PyErr_Clear(); - if (PyModule_Check(obj)) - result = _specialized_dir_module(obj); - else if (PyType_Check(obj)) - result = _specialized_dir_type(obj); - else - result = _generic_dir(obj); + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_TypeError, "object does not provide __dir__"); + return NULL; } - else { - /* use __dir__ */ - result = PyObject_CallFunctionObjArgs(dirfunc, obj, NULL); - Py_DECREF(dirfunc); - if (result == NULL) - return NULL; + /* use __dir__ */ + result = PyObject_CallFunctionObjArgs(dirfunc, NULL); + Py_DECREF(dirfunc); + if (result == NULL) + return NULL; - /* result must be a list */ - /* XXX(gbrandl): could also check if all items are strings */ - if (!PyList_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__dir__() must return a list, not %.200s", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; - } + /* result must be a list */ + /* XXX(gbrandl): could also check if all items are strings */ + if (!PyList_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__dir__() must return a list, not %.200s", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + result = NULL; } return result; diff --git a/Objects/setobject.c b/Objects/setobject.c --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -607,16 +607,18 @@ goto done; newsize = PyUnicode_GET_SIZE(listrepr); result = PyUnicode_FromUnicode(NULL, newsize); - if (result) { - u = PyUnicode_AS_UNICODE(result); - *u++ = '{'; - /* Omit the brackets from the listrepr */ - Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1, - PyUnicode_GET_SIZE(listrepr)-2); - u += newsize-2; - *u++ = '}'; - } + if (result == NULL) + goto done; + + u = PyUnicode_AS_UNICODE(result); + *u++ = '{'; + /* Omit the brackets from the listrepr */ + Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1, + newsize-2); + u += newsize-2; + *u++ = '}'; Py_DECREF(listrepr); + if (Py_TYPE(so) != &PySet_Type) { PyObject *tmp = PyUnicode_FromFormat("%s(%U)", Py_TYPE(so)->tp_name, diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2572,6 +2572,82 @@ return PyDict_New(); } +/* + Merge the __dict__ of aclass into dict, and recursively also all + the __dict__s of aclass's base classes. The order of merging isn't + defined, as it's expected that only the final set of dict keys is + interesting. + Return 0 on success, -1 on error. +*/ + +static int +merge_class_dict(PyObject *dict, PyObject *aclass) +{ + PyObject *classdict; + PyObject *bases; + + assert(PyDict_Check(dict)); + assert(aclass); + + /* Merge in the type's dict (if any). */ + classdict = PyObject_GetAttrString(aclass, "__dict__"); + if (classdict == NULL) + PyErr_Clear(); + else { + int status = PyDict_Update(dict, classdict); + Py_DECREF(classdict); + if (status < 0) + return -1; + } + + /* Recursively merge in the base types' (if any) dicts. */ + bases = PyObject_GetAttrString(aclass, "__bases__"); + if (bases == NULL) + PyErr_Clear(); + else { + /* We have no guarantee that bases is a real tuple */ + Py_ssize_t i, n; + n = PySequence_Size(bases); /* This better be right */ + if (n < 0) + PyErr_Clear(); + else { + for (i = 0; i < n; i++) { + int status; + PyObject *base = PySequence_GetItem(bases, i); + if (base == NULL) { + Py_DECREF(bases); + return -1; + } + status = merge_class_dict(dict, base); + Py_DECREF(base); + if (status < 0) { + Py_DECREF(bases); + return -1; + } + } + } + Py_DECREF(bases); + } + return 0; +} + +/* __dir__ for type objects: returns __dict__ and __bases__. + We deliberately don't suck up its __class__, as methods belonging to the + metaclass would probably be more confusing than helpful. +*/ +static PyObject * +type_dir(PyObject *self, PyObject *args) +{ + PyObject *result = NULL; + PyObject *dict = PyDict_New(); + + if (dict != NULL && merge_class_dict(dict, self) == 0) + result = PyDict_Keys(dict); + + Py_XDECREF(dict); + return result; +} + static PyMethodDef type_methods[] = { {"mro", (PyCFunction)mro_external, METH_NOARGS, PyDoc_STR("mro() -> list\nreturn a type's method resolution order")}, @@ -2582,9 +2658,11 @@ PyDoc_STR("__prepare__() -> dict\n" "used to create the namespace for the class statement")}, {"__instancecheck__", type___instancecheck__, METH_O, - PyDoc_STR("__instancecheck__() -> check if an object is an instance")}, + PyDoc_STR("__instancecheck__() -> bool\ncheck if an object is an instance")}, {"__subclasscheck__", type___subclasscheck__, METH_O, - PyDoc_STR("__subclasscheck__() -> check if a class is a subclass")}, + PyDoc_STR("__subclasscheck__() -> bool\ncheck if a class is a subclass")}, + {"__dir__", type_dir, METH_NOARGS, + PyDoc_STR("__dir__() -> list\nspecialized __dir__ implementation for types")}, {0} }; @@ -3438,6 +3516,53 @@ return PyLong_FromSsize_t(res); } +/* __dir__ for generic objects: returns __dict__, __class__, + and recursively up the __class__.__bases__ chain. +*/ +static PyObject * +object_dir(PyObject *self, PyObject *args) +{ + PyObject *result = NULL; + PyObject *dict = NULL; + PyObject *itsclass = NULL; + + /* Get __dict__ (which may or may not be a real dict...) */ + dict = PyObject_GetAttrString(self, "__dict__"); + if (dict == NULL) { + PyErr_Clear(); + dict = PyDict_New(); + } + else if (!PyDict_Check(dict)) { + Py_DECREF(dict); + dict = PyDict_New(); + } + else { + /* Copy __dict__ to avoid mutating it. */ + PyObject *temp = PyDict_Copy(dict); + Py_DECREF(dict); + dict = temp; + } + + if (dict == NULL) + goto error; + + /* Merge in attrs reachable from its class. */ + itsclass = PyObject_GetAttrString(self, "__class__"); + if (itsclass == NULL) + /* XXX(tomer): Perhaps fall back to obj->ob_type if no + __class__ exists? */ + PyErr_Clear(); + else if (merge_class_dict(dict, itsclass) != 0) + goto error; + + result = PyDict_Keys(dict); + /* fall through */ +error: + Py_XDECREF(itsclass); + Py_XDECREF(dict); + return result; +} + static PyMethodDef object_methods[] = { {"__reduce_ex__", object_reduce_ex, METH_VARARGS, PyDoc_STR("helper for pickle")}, @@ -3448,7 +3573,9 @@ {"__format__", object_format, METH_VARARGS, PyDoc_STR("default object formatter")}, {"__sizeof__", object_sizeof, METH_NOARGS, - PyDoc_STR("__sizeof__() -> size of object in memory, in bytes")}, + PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")}, + {"__dir__", object_dir, METH_NOARGS, + PyDoc_STR("__dir__() -> list\ndefault dir() implementation")}, {0} }; diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -1,4 +1,4 @@ -/* Generated by typeslots.py $Revision$ */ +/* Generated by typeslots.py */ 0, 0, offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript), diff --git a/Objects/typeslots.py b/Objects/typeslots.py --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -3,7 +3,7 @@ import sys, re -print("/* Generated by typeslots.py $Revision$ */") +print("/* Generated by typeslots.py */") res = {} for line in sys.stdin: m = re.match("#define Py_([a-z_]+) ([0-9]+)", line) diff --git a/Parser/Python.asdl b/Parser/Python.asdl --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -28,11 +28,10 @@ | For(expr target, expr iter, stmt* body, stmt* orelse) | While(expr test, stmt* body, stmt* orelse) | If(expr test, stmt* body, stmt* orelse) - | With(expr context_expr, expr? optional_vars, stmt* body) + | With(withitem* items, stmt* body) | Raise(expr? exc, expr? cause) - | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) - | TryFinally(stmt* body, stmt* finalbody) + | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) | Assert(expr test, expr? msg) | Import(alias* names) @@ -115,5 +114,7 @@ -- import name with optional 'as' alias. alias = (identifier name, identifier? asname) + + withitem = (expr context_expr, expr? optional_vars) } diff --git a/Parser/myreadline.c b/Parser/myreadline.c --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -40,6 +40,7 @@ if (PyOS_InputHook != NULL) (void)(PyOS_InputHook)(); errno = 0; + clearerr(fp); p = fgets(buf, len, fp); if (p != NULL) return 0; /* No error */ diff --git a/Parser/parsetok.c b/Parser/parsetok.c --- a/Parser/parsetok.c +++ b/Parser/parsetok.c @@ -232,7 +232,7 @@ PyParser_Delete(ps); if (n == NULL) { - if (tok->lineno <= 1 && tok->done == E_EOF) + if (tok->done == E_EOF) err_ret->error = E_EOF; err_ret->lineno = tok->lineno; if (tok->buf != NULL) { diff --git a/Python/Python-ast.c b/Python/Python-ast.c --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -2,7 +2,7 @@ /* - __version__ 0daa6ba25d9b. + __version__ e0e663132363. This module must be committed separately after each AST grammar change; The __version__ number is set to the revision number of the commit @@ -95,8 +95,7 @@ }; static PyTypeObject *With_type; static char *With_fields[]={ - "context_expr", - "optional_vars", + "items", "body", }; static PyTypeObject *Raise_type; @@ -104,15 +103,11 @@ "exc", "cause", }; -static PyTypeObject *TryExcept_type; -static char *TryExcept_fields[]={ +static PyTypeObject *Try_type; +static char *Try_fields[]={ "body", "handlers", "orelse", -}; -static PyTypeObject *TryFinally_type; -static char *TryFinally_fields[]={ - "body", "finalbody", }; static PyTypeObject *Assert_type; @@ -392,6 +387,12 @@ "name", "asname", }; +static PyTypeObject *withitem_type; +static PyObject* ast2obj_withitem(void*); +static char *withitem_fields[]={ + "context_expr", + "optional_vars", +}; static int @@ -680,15 +681,12 @@ if (!While_type) return 0; If_type = make_type("If", stmt_type, If_fields, 3); if (!If_type) return 0; - With_type = make_type("With", stmt_type, With_fields, 3); + With_type = make_type("With", stmt_type, With_fields, 2); if (!With_type) return 0; Raise_type = make_type("Raise", stmt_type, Raise_fields, 2); if (!Raise_type) return 0; - TryExcept_type = make_type("TryExcept", stmt_type, TryExcept_fields, 3); - if (!TryExcept_type) return 0; - TryFinally_type = make_type("TryFinally", stmt_type, TryFinally_fields, - 2); - if (!TryFinally_type) return 0; + Try_type = make_type("Try", stmt_type, Try_fields, 4); + if (!Try_type) return 0; Assert_type = make_type("Assert", stmt_type, Assert_fields, 2); if (!Assert_type) return 0; Import_type = make_type("Import", stmt_type, Import_fields, 1); @@ -938,6 +936,8 @@ if (!keyword_type) return 0; alias_type = make_type("alias", &AST_type, alias_fields, 2); if (!alias_type) return 0; + withitem_type = make_type("withitem", &AST_type, withitem_fields, 2); + if (!withitem_type) return 0; initialized = 1; return 1; } @@ -960,6 +960,7 @@ static int obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena); static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena); static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena); +static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena); mod_ty Module(asdl_seq * body, PyArena *arena) @@ -1225,21 +1226,15 @@ } stmt_ty -With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno, - int col_offset, PyArena *arena) +With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, PyArena + *arena) { stmt_ty p; - if (!context_expr) { - PyErr_SetString(PyExc_ValueError, - "field context_expr is required for With"); - return NULL; - } p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; p->kind = With_kind; - p->v.With.context_expr = context_expr; - p->v.With.optional_vars = optional_vars; + p->v.With.items = items; p->v.With.body = body; p->lineno = lineno; p->col_offset = col_offset; @@ -1262,33 +1257,18 @@ } stmt_ty -TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno, - int col_offset, PyArena *arena) +Try(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, asdl_seq * + finalbody, int lineno, int col_offset, PyArena *arena) { stmt_ty p; p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; - p->kind = TryExcept_kind; - p->v.TryExcept.body = body; - p->v.TryExcept.handlers = handlers; - p->v.TryExcept.orelse = orelse; - p->lineno = lineno; - p->col_offset = col_offset; - return p; -} - -stmt_ty -TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int col_offset, - PyArena *arena) -{ - stmt_ty p; - p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); - if (!p) - return NULL; - p->kind = TryFinally_kind; - p->v.TryFinally.body = body; - p->v.TryFinally.finalbody = finalbody; + p->kind = Try_kind; + p->v.Try.body = body; + p->v.Try.handlers = handlers; + p->v.Try.orelse = orelse; + p->v.Try.finalbody = finalbody; p->lineno = lineno; p->col_offset = col_offset; return p; @@ -2135,6 +2115,23 @@ return p; } +withitem_ty +withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena) +{ + withitem_ty p; + if (!context_expr) { + PyErr_SetString(PyExc_ValueError, + "field context_expr is required for withitem"); + return NULL; + } + p = (withitem_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->context_expr = context_expr; + p->optional_vars = optional_vars; + return p; +} + PyObject* ast2obj_mod(void* _o) @@ -2390,15 +2387,9 @@ case With_kind: result = PyType_GenericNew(With_type, NULL, NULL); if (!result) goto failed; - value = ast2obj_expr(o->v.With.context_expr); + value = ast2obj_list(o->v.With.items, ast2obj_withitem); if (!value) goto failed; - if (PyObject_SetAttrString(result, "context_expr", value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(o->v.With.optional_vars); - if (!value) goto failed; - if (PyObject_SetAttrString(result, "optional_vars", value) == - -1) + if (PyObject_SetAttrString(result, "items", value) == -1) goto failed; Py_DECREF(value); value = ast2obj_list(o->v.With.body, ast2obj_stmt); @@ -2421,35 +2412,25 @@ goto failed; Py_DECREF(value); break; - case TryExcept_kind: - result = PyType_GenericNew(TryExcept_type, NULL, NULL); + case Try_kind: + result = PyType_GenericNew(Try_type, NULL, NULL); if (!result) goto failed; - value = ast2obj_list(o->v.TryExcept.body, ast2obj_stmt); + value = ast2obj_list(o->v.Try.body, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttrString(result, "body", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(o->v.TryExcept.handlers, - ast2obj_excepthandler); + value = ast2obj_list(o->v.Try.handlers, ast2obj_excepthandler); if (!value) goto failed; if (PyObject_SetAttrString(result, "handlers", value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_list(o->v.TryExcept.orelse, ast2obj_stmt); + value = ast2obj_list(o->v.Try.orelse, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttrString(result, "orelse", value) == -1) goto failed; Py_DECREF(value); - break; - case TryFinally_kind: - result = PyType_GenericNew(TryFinally_type, NULL, NULL); - if (!result) goto failed; - value = ast2obj_list(o->v.TryFinally.body, ast2obj_stmt); - if (!value) goto failed; - if (PyObject_SetAttrString(result, "body", value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_list(o->v.TryFinally.finalbody, ast2obj_stmt); + value = ast2obj_list(o->v.Try.finalbody, ast2obj_stmt); if (!value) goto failed; if (PyObject_SetAttrString(result, "finalbody", value) == -1) goto failed; @@ -3370,6 +3351,35 @@ return NULL; } +PyObject* +ast2obj_withitem(void* _o) +{ + withitem_ty o = (withitem_ty)_o; + PyObject *result = NULL, *value = NULL; + if (!o) { + Py_INCREF(Py_None); + return Py_None; + } + + result = PyType_GenericNew(withitem_type, NULL, NULL); + if (!result) return NULL; + value = ast2obj_expr(o->context_expr); + if (!value) goto failed; + if (PyObject_SetAttrString(result, "context_expr", value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(o->optional_vars); + if (!value) goto failed; + if (PyObject_SetAttrString(result, "optional_vars", value) == -1) + goto failed; + Py_DECREF(value); + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + int obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena) @@ -4210,33 +4220,34 @@ return 1; } if (isinstance) { - expr_ty context_expr; - expr_ty optional_vars; + asdl_seq* items; asdl_seq* body; - if (PyObject_HasAttrString(obj, "context_expr")) { + if (PyObject_HasAttrString(obj, "items")) { int res; - tmp = PyObject_GetAttrString(obj, "context_expr"); + Py_ssize_t len; + Py_ssize_t i; + tmp = PyObject_GetAttrString(obj, "items"); if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &context_expr, arena); - if (res != 0) goto failed; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "With field \"items\" must be a list, not a %.200s", tmp->ob_type->tp_name); + goto failed; + } + len = PyList_GET_SIZE(tmp); + items = asdl_seq_new(len, arena); + if (items == NULL) goto failed; + for (i = 0; i < len; i++) { + withitem_ty value; + res = obj2ast_withitem(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(items, i, value); + } Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from With"); + PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With"); return 1; } - if (PyObject_HasAttrString(obj, "optional_vars")) { - int res; - tmp = PyObject_GetAttrString(obj, "optional_vars"); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &optional_vars, arena); - if (res != 0) goto failed; - Py_XDECREF(tmp); - tmp = NULL; - } else { - optional_vars = NULL; - } if (PyObject_HasAttrString(obj, "body")) { int res; Py_ssize_t len; @@ -4262,8 +4273,7 @@ PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With"); return 1; } - *out = With(context_expr, optional_vars, body, lineno, - col_offset, arena); + *out = With(items, body, lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -4301,7 +4311,7 @@ if (*out == NULL) goto failed; return 0; } - isinstance = PyObject_IsInstance(obj, (PyObject*)TryExcept_type); + isinstance = PyObject_IsInstance(obj, (PyObject*)Try_type); if (isinstance == -1) { return 1; } @@ -4309,6 +4319,7 @@ asdl_seq* body; asdl_seq* handlers; asdl_seq* orelse; + asdl_seq* finalbody; if (PyObject_HasAttrString(obj, "body")) { int res; @@ -4317,7 +4328,7 @@ tmp = PyObject_GetAttrString(obj, "body"); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "TryExcept field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "Try field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); @@ -4332,7 +4343,7 @@ Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryExcept"); + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try"); return 1; } if (PyObject_HasAttrString(obj, "handlers")) { @@ -4342,7 +4353,7 @@ tmp = PyObject_GetAttrString(obj, "handlers"); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "TryExcept field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "Try field \"handlers\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); @@ -4357,7 +4368,7 @@ Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryExcept"); + PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try"); return 1; } if (PyObject_HasAttrString(obj, "orelse")) { @@ -4367,7 +4378,7 @@ tmp = PyObject_GetAttrString(obj, "orelse"); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "TryExcept field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "Try field \"orelse\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); @@ -4382,45 +4393,7 @@ Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryExcept"); - return 1; - } - *out = TryExcept(body, handlers, orelse, lineno, col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - isinstance = PyObject_IsInstance(obj, (PyObject*)TryFinally_type); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - asdl_seq* body; - asdl_seq* finalbody; - - if (PyObject_HasAttrString(obj, "body")) { - int res; - Py_ssize_t len; - Py_ssize_t i; - tmp = PyObject_GetAttrString(obj, "body"); - if (tmp == NULL) goto failed; - if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "TryFinally field \"body\" must be a list, not a %.200s", tmp->ob_type->tp_name); - goto failed; - } - len = PyList_GET_SIZE(tmp); - body = asdl_seq_new(len, arena); - if (body == NULL) goto failed; - for (i = 0; i < len; i++) { - stmt_ty value; - res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena); - if (res != 0) goto failed; - asdl_seq_SET(body, i, value); - } - Py_XDECREF(tmp); - tmp = NULL; - } else { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryFinally"); + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try"); return 1; } if (PyObject_HasAttrString(obj, "finalbody")) { @@ -4430,7 +4403,7 @@ tmp = PyObject_GetAttrString(obj, "finalbody"); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "TryFinally field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "Try field \"finalbody\" must be a list, not a %.200s", tmp->ob_type->tp_name); goto failed; } len = PyList_GET_SIZE(tmp); @@ -4445,10 +4418,11 @@ Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryFinally"); + PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try"); return 1; } - *out = TryFinally(body, finalbody, lineno, col_offset, arena); + *out = Try(body, handlers, orelse, finalbody, lineno, + col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6723,6 +6697,43 @@ return 1; } +int +obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena) +{ + PyObject* tmp = NULL; + expr_ty context_expr; + expr_ty optional_vars; + + if (PyObject_HasAttrString(obj, "context_expr")) { + int res; + tmp = PyObject_GetAttrString(obj, "context_expr"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &context_expr, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + PyErr_SetString(PyExc_TypeError, "required field \"context_expr\" missing from withitem"); + return 1; + } + if (PyObject_HasAttrString(obj, "optional_vars")) { + int res; + tmp = PyObject_GetAttrString(obj, "optional_vars"); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &optional_vars, arena); + if (res != 0) goto failed; + Py_XDECREF(tmp); + tmp = NULL; + } else { + optional_vars = NULL; + } + *out = withitem(context_expr, optional_vars, arena); + return 0; +failed: + Py_XDECREF(tmp); + return 1; +} + static struct PyModuleDef _astmodule = { PyModuleDef_HEAD_INIT, "_ast" @@ -6739,7 +6750,7 @@ NULL; if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0) return NULL; - if (PyModule_AddStringConstant(m, "__version__", "0daa6ba25d9b") < 0) + if (PyModule_AddStringConstant(m, "__version__", "e0e663132363") < 0) return NULL; if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return NULL; @@ -6774,10 +6785,8 @@ NULL; if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return NULL; - if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) < - 0) return NULL; - if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) < - 0) return NULL; + if (PyDict_SetItemString(d, "Try", (PyObject*)Try_type) < 0) return + NULL; if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0) return NULL; if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0) @@ -6940,6 +6949,8 @@ return NULL; if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return NULL; + if (PyDict_SetItemString(d, "withitem", (PyObject*)withitem_type) < 0) + return NULL; return m; } diff --git a/Python/ast.c b/Python/ast.c --- a/Python/ast.c +++ b/Python/ast.c @@ -2893,7 +2893,7 @@ { const int nch = NCH(n); int n_except = (nch - 3)/3; - asdl_seq *body, *orelse = NULL, *finally = NULL; + asdl_seq *body, *handlers = NULL, *orelse = NULL, *finally = NULL; REQ(n, try_stmt); @@ -2934,9 +2934,8 @@ if (n_except > 0) { int i; - stmt_ty except_st; /* process except statements to create a try ... except */ - asdl_seq *handlers = asdl_seq_new(n_except, c->c_arena); + handlers = asdl_seq_new(n_except, c->c_arena); if (handlers == NULL) return NULL; @@ -2947,28 +2946,15 @@ return NULL; asdl_seq_SET(handlers, i, e); } - - except_st = TryExcept(body, handlers, orelse, LINENO(n), - n->n_col_offset, c->c_arena); - if (!finally) - return except_st; - - /* if a 'finally' is present too, we nest the TryExcept within a - TryFinally to emulate try ... except ... finally */ - body = asdl_seq_new(1, c->c_arena); - if (body == NULL) - return NULL; - asdl_seq_SET(body, 0, except_st); } - /* must be a try ... finally (except clauses are in body, if any exist) */ - assert(finally != NULL); - return TryFinally(body, finally, LINENO(n), n->n_col_offset, c->c_arena); + assert(finally != NULL || asdl_seq_LEN(handlers)); + return Try(body, handlers, orelse, finally, LINENO(n), n->n_col_offset, c->c_arena); } /* with_item: test ['as' expr] */ -static stmt_ty -ast_for_with_item(struct compiling *c, const node *n, asdl_seq *content) +static withitem_ty +ast_for_with_item(struct compiling *c, const node *n) { expr_ty context_expr, optional_vars = NULL; @@ -2987,43 +2973,32 @@ } } - return With(context_expr, optional_vars, content, LINENO(n), - n->n_col_offset, c->c_arena); + return withitem(context_expr, optional_vars, c->c_arena); } /* with_stmt: 'with' with_item (',' with_item)* ':' suite */ static stmt_ty ast_for_with_stmt(struct compiling *c, const node *n) { - int i; - stmt_ty ret; - asdl_seq *inner; + int i, n_items; + asdl_seq *items, *body; REQ(n, with_stmt); - /* process the with items inside-out */ - i = NCH(n) - 1; - /* the suite of the innermost with item is the suite of the with stmt */ - inner = ast_for_suite(c, CHILD(n, i)); - if (!inner) + n_items = (NCH(n) - 2) / 2; + items = asdl_seq_new(n_items, c->c_arena); + for (i = 1; i < NCH(n) - 2; i += 2) { + withitem_ty item = ast_for_with_item(c, CHILD(n, i)); + if (!item) + return NULL; + asdl_seq_SET(items, (i - 1) / 2, item); + } + + body = ast_for_suite(c, CHILD(n, NCH(n) - 1)); + if (!body) return NULL; - for (;;) { - i -= 2; - ret = ast_for_with_item(c, CHILD(n, i), inner); - if (!ret) - return NULL; - /* was this the last item? */ - if (i == 1) - break; - /* if not, wrap the result so far in a new sequence */ - inner = asdl_seq_new(1, c->c_arena); - if (!inner) - return NULL; - asdl_seq_SET(inner, 0, ret); - } - - return ret; + return With(items, body, LINENO(n), n->n_col_offset, c->c_arena); } static stmt_ty diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -135,6 +135,7 @@ struct compiler { const char *c_filename; + PyObject *c_filename_obj; struct symtable *c_st; PyFutureFeatures *c_future; /* pointer to module's __future__ */ PyCompilerFlags *c_flags; @@ -178,12 +179,13 @@ static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(struct compiler *, expr_ty); -static int compiler_with(struct compiler *, stmt_ty); +static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_call_helper(struct compiler *c, int n, asdl_seq *args, asdl_seq *keywords, expr_ty starargs, expr_ty kwargs); +static int compiler_try_except(struct compiler *, stmt_ty); static PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__; @@ -272,6 +274,9 @@ if (!compiler_init(&c)) return NULL; c.c_filename = filename; + c.c_filename_obj = PyUnicode_DecodeFSDefault(filename); + if (!c.c_filename_obj) + goto finally; c.c_arena = arena; c.c_future = PyFuture_FromAST(mod, filename); if (c.c_future == NULL) @@ -324,6 +329,8 @@ PySymtable_Free(c->c_st); if (c->c_future) PyObject_Free(c->c_future); + if (c->c_filename_obj) + Py_DECREF(c->c_filename_obj); Py_DECREF(c->c_stack); } @@ -1892,7 +1899,13 @@ compiler_use_next_block(c, body); if (!compiler_push_fblock(c, FINALLY_TRY, body)) return 0; - VISIT_SEQ(c, stmt, s->v.TryFinally.body); + if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { + if (!compiler_try_except(c, s)) + return 0; + } + else { + VISIT_SEQ(c, stmt, s->v.Try.body); + } ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); @@ -1900,7 +1913,7 @@ compiler_use_next_block(c, end); if (!compiler_push_fblock(c, FINALLY_END, end)) return 0; - VISIT_SEQ(c, stmt, s->v.TryFinally.finalbody); + VISIT_SEQ(c, stmt, s->v.Try.finalbody); ADDOP(c, END_FINALLY); compiler_pop_fblock(c, FINALLY_END, end); @@ -1954,15 +1967,15 @@ compiler_use_next_block(c, body); if (!compiler_push_fblock(c, EXCEPT, body)) return 0; - VISIT_SEQ(c, stmt, s->v.TryExcept.body); + VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, EXCEPT, body); ADDOP_JREL(c, JUMP_FORWARD, orelse); - n = asdl_seq_LEN(s->v.TryExcept.handlers); + n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( - s->v.TryExcept.handlers, i); + s->v.Try.handlers, i); if (!handler->v.ExceptHandler.type && i < n-1) return compiler_error(c, "default 'except:' must be last"); c->u->u_lineno_set = 0; @@ -1979,82 +1992,91 @@ } ADDOP(c, POP_TOP); if (handler->v.ExceptHandler.name) { - basicblock *cleanup_end, *cleanup_body; - - cleanup_end = compiler_new_block(c); - cleanup_body = compiler_new_block(c); - if(!(cleanup_end || cleanup_body)) - return 0; - - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - ADDOP(c, POP_TOP); - - /* - try: - # body - except type as name: - try: - # body - finally: - name = None - del name - */ - - /* second try: */ - ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) - return 0; - - /* second # body */ - VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); - - /* finally: */ - ADDOP_O(c, LOAD_CONST, Py_None, consts); - compiler_use_next_block(c, cleanup_end); - if (!compiler_push_fblock(c, FINALLY_END, cleanup_end)) - return 0; - - /* name = None */ - ADDOP_O(c, LOAD_CONST, Py_None, consts); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - - /* del name */ - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - - ADDOP(c, END_FINALLY); - compiler_pop_fblock(c, FINALLY_END, cleanup_end); + basicblock *cleanup_end, *cleanup_body; + + cleanup_end = compiler_new_block(c); + cleanup_body = compiler_new_block(c); + if (!(cleanup_end || cleanup_body)) + return 0; + + compiler_nameop(c, handler->v.ExceptHandler.name, Store); + ADDOP(c, POP_TOP); + + /* + try: + # body + except type as name: + try: + # body + finally: + name = None + del name + */ + + /* second try: */ + ADDOP_JREL(c, SETUP_FINALLY, cleanup_end); + compiler_use_next_block(c, cleanup_body); + if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) + return 0; + + /* second # body */ + VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); + ADDOP(c, POP_BLOCK); + ADDOP(c, POP_EXCEPT); + compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); + + /* finally: */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + compiler_use_next_block(c, cleanup_end); + if (!compiler_push_fblock(c, FINALLY_END, cleanup_end)) + return 0; + + /* name = None */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + compiler_nameop(c, handler->v.ExceptHandler.name, Store); + + /* del name */ + compiler_nameop(c, handler->v.ExceptHandler.name, Del); + + ADDOP(c, END_FINALLY); + compiler_pop_fblock(c, FINALLY_END, cleanup_end); } else { - basicblock *cleanup_body; - - cleanup_body = compiler_new_block(c); - if(!cleanup_body) - return 0; + basicblock *cleanup_body; + + cleanup_body = compiler_new_block(c); + if (!cleanup_body) + return 0; ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) - return 0; + ADDOP(c, POP_TOP); + compiler_use_next_block(c, cleanup_body); + if (!compiler_push_fblock(c, FINALLY_TRY, cleanup_body)) + return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); - ADDOP(c, POP_EXCEPT); - compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); + ADDOP(c, POP_EXCEPT); + compiler_pop_fblock(c, FINALLY_TRY, cleanup_body); } ADDOP_JREL(c, JUMP_FORWARD, end); compiler_use_next_block(c, except); } ADDOP(c, END_FINALLY); compiler_use_next_block(c, orelse); - VISIT_SEQ(c, stmt, s->v.TryExcept.orelse); + VISIT_SEQ(c, stmt, s->v.Try.orelse); compiler_use_next_block(c, end); return 1; } static int +compiler_try(struct compiler *c, stmt_ty s) { + if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody)) + return compiler_try_finally(c, s); + else + return compiler_try_except(c, s); +} + + +static int compiler_import_as(struct compiler *c, identifier name, identifier asname) { /* The IMPORT_NAME opcode was already generated. This function @@ -2301,10 +2323,8 @@ } ADDOP_I(c, RAISE_VARARGS, n); break; - case TryExcept_kind: - return compiler_try_except(c, s); - case TryFinally_kind: - return compiler_try_finally(c, s); + case Try_kind: + return compiler_try(c, s); case Assert_kind: return compiler_assert(c, s); case Import_kind: @@ -2335,7 +2355,7 @@ case Continue_kind: return compiler_continue(c); case With_kind: - return compiler_with(c, s); + return compiler_with(c, s, 0); } return 1; } @@ -3062,9 +3082,10 @@ exit(*exc) */ static int -compiler_with(struct compiler *c, stmt_ty s) +compiler_with(struct compiler *c, stmt_ty s, int pos) { basicblock *block, *finally; + withitem_ty item = asdl_seq_GET(s->v.With.items, pos); assert(s->kind == With_kind); @@ -3074,7 +3095,7 @@ return 0; /* Evaluate EXPR */ - VISIT(c, expr, s->v.With.context_expr); + VISIT(c, expr, item->context_expr); ADDOP_JREL(c, SETUP_WITH, finally); /* SETUP_WITH pushes a finally block. */ @@ -3083,16 +3104,20 @@ return 0; } - if (s->v.With.optional_vars) { - VISIT(c, expr, s->v.With.optional_vars); + if (item->optional_vars) { + VISIT(c, expr, item->optional_vars); } else { /* Discard result from context.__enter__() */ ADDOP(c, POP_TOP); } - /* BLOCK code */ - VISIT_SEQ(c, stmt, s->v.With.body); + pos++; + if (pos == asdl_seq_LEN(s->v.With.items)) + /* BLOCK code */ + VISIT_SEQ(c, stmt, s->v.With.body) + else if (!compiler_with(c, s, pos)) + return 0; /* End of try block; start the finally block */ ADDOP(c, POP_BLOCK); @@ -3361,7 +3386,7 @@ static int compiler_error(struct compiler *c, const char *errstr) { - PyObject *loc, *filename; + PyObject *loc; PyObject *u = NULL, *v = NULL; loc = PyErr_ProgramText(c->c_filename, c->u->u_lineno); @@ -3369,16 +3394,7 @@ Py_INCREF(Py_None); loc = Py_None; } - if (c->c_filename != NULL) { - filename = PyUnicode_DecodeFSDefault(c->c_filename); - if (!filename) - goto exit; - } - else { - Py_INCREF(Py_None); - filename = Py_None; - } - u = Py_BuildValue("(NiiO)", filename, c->u->u_lineno, + u = Py_BuildValue("(OiiO)", c->c_filename_obj, c->u->u_lineno, c->u->u_col_offset, loc); if (!u) goto exit; @@ -3927,7 +3943,6 @@ PyObject *consts = NULL; PyObject *names = NULL; PyObject *varnames = NULL; - PyObject *filename = NULL; PyObject *name = NULL; PyObject *freevars = NULL; PyObject *cellvars = NULL; @@ -3951,10 +3966,6 @@ freevars = dict_keys_inorder(c->u->u_freevars, PyTuple_Size(cellvars)); if (!freevars) goto error; - filename = PyUnicode_DecodeFSDefault(c->c_filename); - if (!filename) - goto error; - nlocals = PyDict_Size(c->u->u_varnames); flags = compute_code_flags(c); if (flags < 0) @@ -3974,14 +3985,13 @@ nlocals, stackdepth(c), flags, bytecode, consts, names, varnames, freevars, cellvars, - filename, c->u->u_name, + c->c_filename_obj, c->u->u_name, c->u->u_firstlineno, a->a_lnotab); error: Py_XDECREF(consts); Py_XDECREF(names); Py_XDECREF(varnames); - Py_XDECREF(filename); Py_XDECREF(name); Py_XDECREF(freevars); Py_XDECREF(cellvars); diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -110,8 +110,12 @@ TAG and PYC_TAG_UNICODE must change for each major Python release. The magic number will take care of any bytecode changes that occur during development. */ +#define QUOTE(arg) #arg +#define STRIFY(name) QUOTE(name) +#define MAJOR STRIFY(PY_MAJOR_VERSION) +#define MINOR STRIFY(PY_MINOR_VERSION) #define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24)) -#define TAG "cpython-32" +#define TAG "cpython-" MAJOR MINOR; #define CACHEDIR "__pycache__" static const Py_UNICODE CACHEDIR_UNICODE[] = { '_', '_', 'p', 'y', 'c', 'a', 'c', 'h', 'e', '_', '_', '\0'}; @@ -119,7 +123,11 @@ static long pyc_magic = MAGIC; static const char *pyc_tag = TAG; static const Py_UNICODE PYC_TAG_UNICODE[] = { - 'c', 'p', 'y', 't', 'h', 'o', 'n', '-', '3', '2', '\0'}; + 'c', 'p', 'y', 't', 'h', 'o', 'n', '-', PY_MAJOR_VERSION + 48, PY_MINOR_VERSION + 48, '\0'}; +#undef QUOTE +#undef STRIFY +#undef MAJOR +#undef MINOR /* See _PyImport_FixupExtensionObject() below */ static PyObject *extensions = NULL; @@ -1733,7 +1741,6 @@ Py_UNICODE buf[MAXPATHLEN+1]; Py_ssize_t buflen = MAXPATHLEN+1; PyObject *path_unicode, *filename; - const Py_UNICODE *base; Py_ssize_t len; struct stat statbuf; static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; @@ -1751,7 +1758,6 @@ else return 0; - base = PyUnicode_AS_UNICODE(path_unicode); len = PyUnicode_GET_SIZE(path_unicode); if (len + 2 + PyUnicode_GET_SIZE(name) + MAXSUFFIXSIZE >= buflen) { Py_DECREF(path_unicode); @@ -2275,12 +2281,10 @@ static int find_init_module(PyObject *directory) { - size_t len; struct stat statbuf; PyObject *filename; int match; - len = PyUnicode_GET_SIZE(directory); filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP); if (filename == NULL) return -1; @@ -2818,7 +2822,7 @@ } PyObject * -PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, +PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { PyObject *nameobj, *mod; diff --git a/Python/marshal.c b/Python/marshal.c --- a/Python/marshal.c +++ b/Python/marshal.c @@ -58,9 +58,9 @@ int depth; /* If fp == NULL, the following are valid: */ PyObject *str; + PyObject *current_filename; char *ptr; char *end; - PyObject *strings; /* dict on marshal, list on unmarshal */ int version; } WFILE; @@ -444,7 +444,6 @@ wf.fp = fp; wf.error = WFERR_OK; wf.depth = 0; - wf.strings = NULL; wf.version = version; w_long(x, &wf); } @@ -456,10 +455,8 @@ wf.fp = fp; wf.error = WFERR_OK; wf.depth = 0; - wf.strings = (version > 0) ? PyDict_New() : NULL; wf.version = version; w_object(x, &wf); - Py_XDECREF(wf.strings); } typedef WFILE RFILE; /* Same struct with different invariants */ @@ -980,6 +977,18 @@ filename = r_object(p); if (filename == NULL) goto code_error; + if (PyUnicode_CheckExact(filename)) { + if (p->current_filename != NULL) { + if (!PyUnicode_Compare(filename, p->current_filename)) { + Py_DECREF(filename); + Py_INCREF(p->current_filename); + filename = p->current_filename; + } + } + else { + p->current_filename = filename; + } + } name = r_object(p); if (name == NULL) goto code_error; @@ -1041,7 +1050,7 @@ RFILE rf; assert(fp); rf.fp = fp; - rf.strings = NULL; + rf.current_filename = NULL; rf.end = rf.ptr = NULL; return r_short(&rf); } @@ -1051,7 +1060,7 @@ { RFILE rf; rf.fp = fp; - rf.strings = NULL; + rf.current_filename = NULL; rf.ptr = rf.end = NULL; return r_long(&rf); } @@ -1112,11 +1121,10 @@ RFILE rf; PyObject *result; rf.fp = fp; - rf.strings = PyList_New(0); + rf.current_filename = NULL; rf.depth = 0; rf.ptr = rf.end = NULL; result = r_object(&rf); - Py_DECREF(rf.strings); return result; } @@ -1126,12 +1134,11 @@ RFILE rf; PyObject *result; rf.fp = NULL; + rf.current_filename = NULL; rf.ptr = str; rf.end = str + len; - rf.strings = PyList_New(0); rf.depth = 0; result = r_object(&rf); - Py_DECREF(rf.strings); return result; } @@ -1150,9 +1157,7 @@ wf.error = WFERR_OK; wf.depth = 0; wf.version = version; - wf.strings = (version > 0) ? PyDict_New() : NULL; w_object(x, &wf); - Py_XDECREF(wf.strings); if (wf.str != NULL) { char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str); if (wf.ptr - base > PY_SSIZE_T_MAX) { @@ -1226,6 +1231,7 @@ if (data == NULL) return NULL; rf.fp = NULL; + rf.current_filename = NULL; if (PyBytes_Check(data)) { rf.ptr = PyBytes_AS_STRING(data); rf.end = rf.ptr + PyBytes_GET_SIZE(data); @@ -1242,10 +1248,8 @@ Py_DECREF(data); return NULL; } - rf.strings = PyList_New(0); rf.depth = 0; result = read_object(&rf); - Py_DECREF(rf.strings); Py_DECREF(data); return result; } @@ -1296,12 +1300,11 @@ s = p.buf; n = p.len; rf.fp = NULL; + rf.current_filename = NULL; rf.ptr = s; rf.end = s + n; - rf.strings = PyList_New(0); rf.depth = 0; result = read_object(&rf); - Py_DECREF(rf.strings); PyBuffer_Release(&p); return result; } diff --git a/Python/pythonrun.c b/Python/pythonrun.c --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -1593,7 +1593,7 @@ moduleName = PyObject_GetAttrString(type, "__module__"); if (moduleName == NULL || !PyUnicode_Check(moduleName)) { - Py_DECREF(moduleName); + Py_XDECREF(moduleName); err = PyFile_WriteString("", f); } else { diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -185,6 +185,7 @@ static int symtable_visit_argannotations(struct symtable *st, asdl_seq *args); static int symtable_implicit_arg(struct symtable *st, int pos); static int symtable_visit_annotations(struct symtable *st, stmt_ty s); +static int symtable_visit_withitem(struct symtable *st, withitem_ty item); static identifier top = NULL, lambda = NULL, genexpr = NULL, @@ -1210,14 +1211,11 @@ } } break; - case TryExcept_kind: - VISIT_SEQ(st, stmt, s->v.TryExcept.body); - VISIT_SEQ(st, stmt, s->v.TryExcept.orelse); - VISIT_SEQ(st, excepthandler, s->v.TryExcept.handlers); - break; - case TryFinally_kind: - VISIT_SEQ(st, stmt, s->v.TryFinally.body); - VISIT_SEQ(st, stmt, s->v.TryFinally.finalbody); + case Try_kind: + VISIT_SEQ(st, stmt, s->v.Try.body); + VISIT_SEQ(st, stmt, s->v.Try.orelse); + VISIT_SEQ(st, excepthandler, s->v.Try.handlers); + VISIT_SEQ(st, stmt, s->v.Try.finalbody); break; case Assert_kind: VISIT(st, expr, s->v.Assert.test); @@ -1305,10 +1303,7 @@ /* nothing to do here */ break; case With_kind: - VISIT(st, expr, s->v.With.context_expr); - if (s->v.With.optional_vars) { - VISIT(st, expr, s->v.With.optional_vars); - } + VISIT_SEQ(st, withitem, s->v.With.items); VISIT_SEQ(st, stmt, s->v.With.body); break; } @@ -1540,6 +1535,16 @@ return 1; } +static int +symtable_visit_withitem(struct symtable *st, withitem_ty item) +{ + VISIT(st, expr, item->context_expr); + if (item->optional_vars) { + VISIT(st, expr, item->optional_vars); + } + return 1; +} + static int symtable_visit_alias(struct symtable *st, alias_ty a) diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -18,6 +18,18 @@ #ifndef THREAD_STACK_SIZE #define THREAD_STACK_SIZE 0 /* use default stack size */ #endif + +#if (defined(__APPLE__) || defined(__FreeBSD__)) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0 + /* The default stack size for new threads on OSX is small enough that + * we'll get hard crashes instead of 'maximum recursion depth exceeded' + * exceptions. + * + * The default stack size below is the minimal stack size where a + * simple recursive function doesn't cause a hard crash. + */ +#undef THREAD_STACK_SIZE +#define THREAD_STACK_SIZE 0x400000 +#endif /* for safety, ensure a viable minimum stacksize */ #define THREAD_STACK_MIN 0x8000 /* 32kB */ #else /* !_POSIX_THREAD_ATTR_STACKSIZE */ diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1031,6 +1031,8 @@ lib.glob("*.0") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") + if dir=='cjkencodings': + lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='xmltestdata': diff --git a/Tools/scripts/findnocoding.py b/Tools/scripts/findnocoding.py --- a/Tools/scripts/findnocoding.py +++ b/Tools/scripts/findnocoding.py @@ -2,7 +2,7 @@ """List all those Python files that require a coding directive -Usage: nocoding.py dir1 [dir2...] +Usage: findnocoding.py dir1 [dir2...] """ __author__ = "Oleg Broytmann, Georg Brandl" @@ -50,7 +50,7 @@ def needs_declaration(fullpath): try: - infile = open(fullpath, 'rU') + infile = open(fullpath) except IOError: # Oops, the file was removed - ignore it return None diff --git a/Tools/scripts/pysource.py b/Tools/scripts/pysource.py --- a/Tools/scripts/pysource.py +++ b/Tools/scripts/pysource.py @@ -42,7 +42,7 @@ return None try: - return open(fullpath, 'rU') + return open(fullpath) except IOError as err: # Access denied, or a special file - ignore it print_debug("%s: access denied: %s" % (fullpath, err)) return None diff --git a/Tools/unittestgui/unittestgui.py b/Tools/unittestgui/unittestgui.py --- a/Tools/unittestgui/unittestgui.py +++ b/Tools/unittestgui/unittestgui.py @@ -28,7 +28,6 @@ """ __author__ = "Steve Purcell (stephen_purcell at yahoo.com)" -__version__ = "$Revision: 1.7 $"[11:-2] import sys import traceback diff --git a/configure b/configure --- a/configure +++ b/configure @@ -1,14 +1,13 @@ #! /bin/sh -# From configure.in Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for python 3.3. +# Generated by GNU Autoconf 2.65 for python 3.3. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software -# Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -320,7 +319,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -360,19 +359,19 @@ fi # as_fn_arith -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. +# script with status $?, using 1 if that was 0. as_fn_error () { - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi - $as_echo "$as_me: error: $2" >&2 + $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error @@ -534,7 +533,7 @@ exec 6>&1 # Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -636,10 +635,8 @@ INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -HAS_HG -HGBRANCH -HGTAG -HGVERSION +HAS_PYTHON +DISABLE_ASDLGEN ARFLAGS AR RANLIB @@ -690,6 +687,10 @@ CONFIG_ARGS SOVERSION VERSION +HAS_HG +HGBRANCH +HGTAG +HGVERSION target_alias host_alias build_alias @@ -832,9 +833,8 @@ fi case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -879,7 +879,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -905,7 +905,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1109,7 +1109,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1125,7 +1125,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1155,8 +1155,8 @@ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) as_fn_error "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information." ;; *=*) @@ -1164,7 +1164,7 @@ # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + as_fn_error "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1182,13 +1182,13 @@ if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" + as_fn_error "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1211,7 +1211,7 @@ [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1225,8 +1225,8 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used" >&2 + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1241,9 +1241,9 @@ ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" + as_fn_error "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" + as_fn_error "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1282,11 +1282,11 @@ fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1326,7 +1326,7 @@ --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1511,9 +1511,9 @@ if $ac_init_version; then cat <<\_ACEOF python configure 3.3 -generated by GNU Autoconf 2.67 - -Copyright (C) 2010 Free Software Foundation, Inc. +generated by GNU Autoconf 2.65 + +Copyright (C) 2009 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1629,7 +1629,7 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { + test $ac_status = 0; } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1653,10 +1653,10 @@ ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1692,7 +1692,7 @@ else ac_header_preproc=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -1715,15 +1715,17 @@ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## -------------------------------------- ## +( cat <<\_ASBOX +## -------------------------------------- ## ## Report this to http://bugs.python.org/ ## -## -------------------------------------- ##" +## -------------------------------------- ## +_ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -1787,7 +1789,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1818,7 +1820,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1872,7 +1874,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1902,7 +1904,8 @@ esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : + eval as_val=\$$3 + if test "x$as_val" = x""no; then : else break @@ -1925,7 +1928,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1976,7 +1979,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if eval test \"x\$"$3"\" = x"no"; then : + eval as_val=\$$3 + if test "x$as_val" = x""no; then : else break @@ -2176,7 +2180,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2244,7 +2248,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } -if eval "test \"\${$4+set}\"" = set; then : +if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2292,18 +2296,15 @@ } # ac_fn_c_check_member -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. +# ac_fn_c_check_decl LINENO SYMBOL VAR +# ------------------------------------ +# Tests whether SYMBOL is declared, setting cache variable VAR accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5 +$as_echo_n "checking whether $2 is declared... " >&6; } +if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2312,12 +2313,8 @@ int main () { -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif +#ifndef $2 + (void) $2; #endif ; @@ -2342,7 +2339,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by python $as_me 3.3, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2452,9 +2449,11 @@ { echo - $as_echo "## ---------------- ## + cat <<\_ASBOX +## ---------------- ## ## Cache variables. ## -## ---------------- ##" +## ---------------- ## +_ASBOX echo # The following way of writing the cache mishandles newlines in values, ( @@ -2488,9 +2487,11 @@ ) echo - $as_echo "## ----------------- ## + cat <<\_ASBOX +## ----------------- ## ## Output variables. ## -## ----------------- ##" +## ----------------- ## +_ASBOX echo for ac_var in $ac_subst_vars do @@ -2503,9 +2504,11 @@ echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + cat <<\_ASBOX +## ------------------- ## ## File substitutions. ## -## ------------------- ##" +## ------------------- ## +_ASBOX echo for ac_var in $ac_subst_files do @@ -2519,9 +2522,11 @@ fi if test -s confdefs.h; then - $as_echo "## ----------- ## + cat <<\_ASBOX +## ----------- ## ## confdefs.h. ## -## ----------- ##" +## ----------- ## +_ASBOX echo cat confdefs.h echo @@ -2576,12 +2581,7 @@ ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2596,11 +2596,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } + . "$ac_site_file" fi done @@ -2676,7 +2672,7 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2690,6 +2686,65 @@ + + + + +if test -e $srcdir/.hg/00changelog.i +then +# Extract the first word of "hg", so it can be a program name with args. +set dummy hg; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_HAS_HG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAS_HG"; then + ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_HAS_HG="found" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" +fi +fi +HAS_HG=$ac_cv_prog_HAS_HG +if test -n "$HAS_HG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 +$as_echo "$HAS_HG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +else +HAS_HG=no-repository +fi +if test $HAS_HG = found +then + HGVERSION="hg id -i \$(srcdir)" + HGTAG="hg id -t \$(srcdir)" + HGBRANCH="hg id -b \$(srcdir)" +else + HGVERSION="" + HGTAG="" + HGBRANCH="" +fi + + ac_config_headers="$ac_config_headers pyconfig.h" @@ -2777,7 +2832,7 @@ UNIVERSALSDK=$enableval if test ! -d "${UNIVERSALSDK}" then - as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 + as_fn_error "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 fi ;; esac @@ -3169,7 +3224,7 @@ # If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then - as_fn_error $? "cached CC is different -- throw away $cache_file + as_fn_error "cached CC is different -- throw away $cache_file (it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5 fi @@ -3479,8 +3534,8 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "no acceptable C compiler found in \$PATH +See \`config.log' for more details." "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -3594,8 +3649,9 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "C compiler cannot create executables +See \`config.log' for more details." "$LINENO" 5; }; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3637,8 +3693,8 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3695,9 +3751,9 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. +as_fn_error "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details." "$LINENO" 5; } fi fi fi @@ -3748,8 +3804,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "cannot compute suffix of object files: cannot compile +See \`config.log' for more details." "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -4232,7 +4288,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4248,11 +4304,11 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4291,7 +4347,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4307,18 +4363,18 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +as_fn_error "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." "$LINENO" 5; } fi ac_ext=c @@ -4379,7 +4435,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP @@ -4445,7 +4501,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP @@ -4577,7 +4633,8 @@ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -5140,17 +5197,16 @@ fi - - -# Extract the first word of "hg", so it can be a program name with args. -set dummy hg; ac_word=$2 +DISABLE_ASDLGEN="" +# Extract the first word of "python", so it can be a program name with args. +set dummy python; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_HAS_HG+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$HAS_HG"; then - ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. +if test "${ac_cv_prog_HAS_PYTHON+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$HAS_PYTHON"; then + ac_cv_prog_HAS_PYTHON="$HAS_PYTHON" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -5159,7 +5215,7 @@ test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_HAS_HG="found" + ac_cv_prog_HAS_PYTHON="found" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -5167,29 +5223,24 @@ done IFS=$as_save_IFS - test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" -fi -fi -HAS_HG=$ac_cv_prog_HAS_HG -if test -n "$HAS_HG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 -$as_echo "$HAS_HG" >&6; } + test -z "$ac_cv_prog_HAS_PYTHON" && ac_cv_prog_HAS_PYTHON="not-found" +fi +fi +HAS_PYTHON=$ac_cv_prog_HAS_PYTHON +if test -n "$HAS_PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_PYTHON" >&5 +$as_echo "$HAS_PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -if test $HAS_HG = found -then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" -else - HGVERSION="" - HGTAG="" - HGBRANCH="" -fi +if test $HAS_HG != found -o $HAS_PYTHON != found +then + DISABLE_ASDLGEN="@echo hg: $HAS_HG, python: $HAS_PYTHON! cannot run \$(srcdir)/Parser/asdl_c.py #" +fi + case $MACHDEP in bsdos*|hp*|HP*) @@ -5201,22 +5252,16 @@ esac ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi + for ac_t in install-sh install.sh shtool; do + if test -f "$ac_dir/$ac_t"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/$ac_t -c" + break 2 + fi + done done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -5554,7 +5599,7 @@ ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" else - as_fn_error $? "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 + as_fn_error "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 fi @@ -6042,7 +6087,8 @@ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -6056,7 +6102,7 @@ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if eval "test \"\${$as_ac_Header+set}\"" = set; then : +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6083,7 +6129,8 @@ eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +eval as_val=\$$as_ac_Header + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF @@ -6608,8 +6655,9 @@ if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (int) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (int) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_int=0 fi @@ -6641,8 +6689,9 @@ if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long=0 fi @@ -6674,8 +6723,9 @@ if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (void *) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_void_p=0 fi @@ -6707,8 +6757,9 @@ if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (short) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (short) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_short=0 fi @@ -6740,8 +6791,9 @@ if test "$ac_cv_type_float" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (float) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (float) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_float=0 fi @@ -6773,8 +6825,9 @@ if test "$ac_cv_type_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (double) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (double) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_double=0 fi @@ -6806,8 +6859,9 @@ if test "$ac_cv_type_fpos_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (fpos_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (fpos_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_fpos_t=0 fi @@ -6839,8 +6893,9 @@ if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (size_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (size_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_size_t=0 fi @@ -6872,8 +6927,9 @@ if test "$ac_cv_type_pid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (pid_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (pid_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_pid_t=0 fi @@ -6932,8 +6988,9 @@ if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long long) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long long) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long_long=0 fi @@ -6993,8 +7050,9 @@ if test "$ac_cv_type_long_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long double) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (long double) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_long_double=0 fi @@ -7055,8 +7113,9 @@ if test "$ac_cv_type__Bool" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (_Bool) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (_Bool) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof__Bool=0 fi @@ -7103,8 +7162,9 @@ if test "$ac_cv_type_uintptr_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (uintptr_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (uintptr_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_uintptr_t=0 fi @@ -7144,8 +7204,9 @@ if test "$ac_cv_type_off_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (off_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (off_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_off_t=0 fi @@ -7206,8 +7267,9 @@ if test "$ac_cv_type_time_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (time_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (time_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_time_t=0 fi @@ -7278,8 +7340,9 @@ if test "$ac_cv_type_pthread_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (pthread_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (pthread_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_pthread_t=0 fi @@ -7366,7 +7429,7 @@ MACOSX_DEFAULT_ARCH="ppc" ;; *) - as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac else @@ -7378,7 +7441,7 @@ MACOSX_DEFAULT_ARCH="ppc64" ;; *) - as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac @@ -7404,7 +7467,7 @@ $as_echo "yes" >&6; } if test $enable_shared = "yes" then - as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 + as_fn_error "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -8244,12 +8307,12 @@ withval=$with_dbmliborder; if test x$with_dbmliborder = xyes then -as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 +as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 else for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb then - as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 + as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 fi done fi @@ -9222,7 +9285,7 @@ $as_echo "#define WITH_VALGRIND 1" >>confdefs.h else - as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5 + as_fn_error "Valgrind support requested but headers not available" "$LINENO" 5 fi @@ -9307,7 +9370,7 @@ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \ - mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \ + mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise pread \ pthread_init pthread_kill putenv pwrite readlink readlinkat readv realpath renameat \ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ @@ -9321,7 +9384,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10344,7 +10408,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10353,44 +10418,25 @@ done -ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" -if test "x$ac_cv_func_dup2" = x""yes; then : - $as_echo "#define HAVE_DUP2 1" >>confdefs.h +for ac_func in dup2 getcwd strdup +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF else case " $LIBOBJS " in - *" dup2.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS dup2.$ac_objext" + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; esac fi - -ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" -if test "x$ac_cv_func_getcwd" = x""yes; then : - $as_echo "#define HAVE_GETCWD 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" getcwd.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS getcwd.$ac_objext" - ;; -esac - -fi - -ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" -if test "x$ac_cv_func_strdup" = x""yes; then : - $as_echo "#define HAVE_STRDUP 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" strdup.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strdup.$ac_objext" - ;; -esac - -fi +done for ac_func in getpgrp @@ -11603,7 +11649,7 @@ then LIBM=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 $as_echo "set LIBM=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 +else as_fn_error "proper usage is --with-libm=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 @@ -11627,7 +11673,7 @@ then LIBC=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 $as_echo "set LIBC=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 +else as_fn_error "proper usage is --with-libc=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 @@ -11877,7 +11923,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -11889,7 +11936,8 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +eval as_val=\$$as_ac_var + if test "x$as_val" = x""yes; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -12152,7 +12200,7 @@ 15|30) ;; *) - as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; + as_fn_error "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 $as_echo "$enable_big_digits" >&6; } @@ -12203,8 +12251,9 @@ if test "$ac_cv_type_wchar_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (wchar_t) -See \`config.log' for more details" "$LINENO" 5 ; } +{ as_fn_set_status 77 +as_fn_error "cannot compute sizeof (wchar_t) +See \`config.log' for more details." "$LINENO" 5; }; } else ac_cv_sizeof_wchar_t=0 fi @@ -12573,8 +12622,8 @@ ;; #( *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + as_fn_error "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac @@ -12835,7 +12884,7 @@ have_readline=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13009,7 +13058,7 @@ have_readline=no fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13824,14 +13873,6 @@ esac -ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" -if test "x$ac_cv_func_pipe2" = x""yes; then : - -$as_echo "#define HAVE_PIPE2 1" >>confdefs.h - -fi - - for h in `(cd $srcdir;echo Python/thread_*.h)` @@ -13939,7 +13980,6 @@ ac_libobjs= ac_ltlibobjs= -U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -14102,19 +14142,19 @@ (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- +# as_fn_error ERROR [LINENO LOG_FD] +# --------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. +# script with status $?, using 1 if that was 0. as_fn_error () { - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + as_status=$?; test $as_status -eq 0 && as_status=1 + if test "$3"; then + as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 fi - $as_echo "$as_me: error: $2" >&2 + $as_echo "$as_me: error: $1" >&2 as_fn_exit $as_status } # as_fn_error @@ -14310,7 +14350,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -14364,7 +14404,7 @@ # values after options handling. ac_log=" This file was extended by python $as_me 3.3, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -14426,10 +14466,10 @@ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ python config.status 3.3 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" -Copyright (C) 2010 Free Software Foundation, Inc. +Copyright (C) 2009 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -14445,16 +14485,11 @@ while test $# != 0 do case $1 in - --*=?*) + --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; *) ac_option=$1 ac_optarg=$2 @@ -14476,7 +14511,6 @@ $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -14489,7 +14523,7 @@ ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' + as_fn_error "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -14498,7 +14532,7 @@ ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' + -*) as_fn_error "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -14557,7 +14591,7 @@ "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -14594,7 +14628,7 @@ { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -14611,7 +14645,7 @@ fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' + ac_cs_awk_cr='\r' else ac_cs_awk_cr=$ac_cr fi @@ -14625,18 +14659,18 @@ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14725,28 +14759,20 @@ else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and + || as_fn_error "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// s/^[^=]*=[ ]*$// }' fi @@ -14774,7 +14800,7 @@ if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14859,7 +14885,7 @@ _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 + as_fn_error "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -14872,7 +14898,7 @@ esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -14900,7 +14926,7 @@ [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -14927,7 +14953,7 @@ case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -15058,22 +15084,22 @@ $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 +which seems to be undefined. Please make sure it is defined." >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} +which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -15084,19 +15110,19 @@ $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + || as_fn_error "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 + || as_fn_error "could not create -" "$LINENO" 5 fi ;; @@ -15116,7 +15142,7 @@ ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -15137,7 +15163,7 @@ exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 + $ac_cs_success || as_fn_exit $? fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -7,8 +7,29 @@ AC_PREREQ(2.65) -AC_REVISION($Revision$) AC_INIT(python, PYTHON_VERSION, http://bugs.python.org/) + +AC_SUBST(HGVERSION) +AC_SUBST(HGTAG) +AC_SUBST(HGBRANCH) + +if test -e $srcdir/.hg/00changelog.i +then +AC_CHECK_PROG(HAS_HG, hg, found, not-found) +else +HAS_HG=no-repository +fi +if test $HAS_HG = found +then + HGVERSION="hg id -i \$(srcdir)" + HGTAG="hg id -t \$(srcdir)" + HGBRANCH="hg id -b \$(srcdir)" +else + HGVERSION="" + HGTAG="" + HGBRANCH="" +fi + AC_CONFIG_SRCDIR([Include/object.h]) AC_CONFIG_HEADER(pyconfig.h) @@ -808,21 +829,15 @@ ARFLAGS="rc" fi -AC_SUBST(HGVERSION) -AC_SUBST(HGTAG) -AC_SUBST(HGBRANCH) -AC_CHECK_PROG(HAS_HG, hg, found, not-found) -if test $HAS_HG = found +AC_SUBST(DISABLE_ASDLGEN) +DISABLE_ASDLGEN="" +AC_CHECK_PROG(HAS_PYTHON, python, found, not-found) +if test $HAS_HG != found -o $HAS_PYTHON != found then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" -else - HGVERSION="" - HGTAG="" - HGBRANCH="" + DISABLE_ASDLGEN="@echo hg: $HAS_HG, python: $HAS_PYTHON! cannot run \$(srcdir)/Parser/asdl_c.py #" fi + case $MACHDEP in bsdos*|hp*|HP*) # install -d does not work on BSDI or HP-UX @@ -2531,7 +2546,7 @@ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \ - mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \ + mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \ posix_fallocate posix_fadvise pread \ pthread_init pthread_kill putenv pwrite readlink readlinkat readv realpath renameat \ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ @@ -4244,8 +4259,6 @@ esac -AC_CHECK_FUNC(pipe2, AC_DEFINE(HAVE_PIPE2, 1, [Define if the OS supports pipe2()]), ) - AC_SUBST(THREADHEADERS) for h in `(cd $srcdir;echo Python/thread_*.h)` diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -560,7 +560,7 @@ /* Define to 1 if you have the `pause' function. */ #undef HAVE_PAUSE -/* Define if the OS supports pipe2() */ +/* Define to 1 if you have the `pipe2' function. */ #undef HAVE_PIPE2 /* Define to 1 if you have the `plock' function. */ diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,8 +1,6 @@ # Autodetecting setup.py script for building the Python extensions # -__version__ = "$Revision$" - import sys, os, imp, re, optparse from glob import glob import sysconfig @@ -1889,7 +1887,7 @@ # check the PyBuildScripts command above, and change the links # created by the bininstall target in Makefile.pre.in scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", - "Tools/scripts/2to3"] + "Tools/scripts/2to3", "Tools/scripts/pysetup3"] ) # --install-platlib -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 10:31:59 2011 From: python-checkins at python.org (vinay.sajip) Date: Sun, 05 Jun 2011 10:31:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Closes_issue_=2311557=3A_re?= =?utf8?q?moval_of_non-idiomatic_code_in_test=5Flogging=2E?= Message-ID: http://hg.python.org/cpython/rev/44139ece7a31 changeset: 70642:44139ece7a31 user: Vinay Sajip date: Sun Jun 05 09:31:34 2011 +0100 summary: Closes issue #11557: removal of non-idiomatic code in test_logging. files: Lib/test/test_logging.py | 58 ++++++++++++--------------- 1 files changed, 26 insertions(+), 32 deletions(-) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -158,8 +158,7 @@ except AttributeError: # StringIO.StringIO lacks a reset() method. actual_lines = stream.getvalue().splitlines() - self.assertEqual(len(actual_lines), len(expected_values), - '%s vs. %s' % (actual_lines, expected_values)) + self.assertEqual(len(actual_lines), len(expected_values)) for actual, expected in zip(actual_lines, expected_values): match = pat.search(actual) if not match: @@ -599,8 +598,8 @@ h = logging.StreamHandler(BadStream()) sys.stderr = sio = io.StringIO() h.handle(r) - self.assertTrue('\nRuntimeError: ' - 'deliberate mistake\n' in sio.getvalue()) + self.assertIn('\nRuntimeError: deliberate mistake\n', + sio.getvalue()) logging.raiseExceptions = False sys.stderr = sio = io.StringIO() h.handle(r) @@ -940,7 +939,7 @@ peer, mailfrom, rcpttos, data = self.messages[0] self.assertEqual(mailfrom, 'me') self.assertEqual(rcpttos, ['you']) - self.assertTrue('\nSubject: Log\n' in data) + self.assertIn('\nSubject: Log\n', data) self.assertTrue(data.endswith('\n\nHello')) h.close() @@ -1692,7 +1691,7 @@ def test_warnings(self): with warnings.catch_warnings(): logging.captureWarnings(True) - self.addCleanup(lambda: logging.captureWarnings(False)) + self.addCleanup(logging.captureWarnings, False) warnings.filterwarnings("always", category=UserWarning) stream = io.StringIO() h = logging.StreamHandler(stream) @@ -1716,14 +1715,14 @@ def test_warnings_no_handlers(self): with warnings.catch_warnings(): logging.captureWarnings(True) - self.addCleanup(lambda: logging.captureWarnings(False)) + self.addCleanup(logging.captureWarnings, False) # confirm our assumption: no loggers are set logger = logging.getLogger("py.warnings") - assert logger.handlers == [] + self.assertEqual(logger.handlers, []) warnings.showwarning("Explicit", UserWarning, "dummy.py", 42) - self.assertTrue(len(logger.handlers) == 1) + self.assertEqual(len(logger.handlers), 1) self.assertIsInstance(logger.handlers[0], logging.NullHandler) @@ -2971,7 +2970,7 @@ self.called = [] raise_exceptions = logging.raiseExceptions - self.addCleanup(lambda: setattr(logging, 'raiseExceptions', raise_exceptions)) + self.addCleanup(setattr, logging, 'raiseExceptions', raise_exceptions) def raise_error(self, error): def inner(): @@ -3056,8 +3055,8 @@ def test_disable(self): old_disable = logging.root.manager.disable # confirm our assumptions are correct - assert old_disable == 0 - self.addCleanup(lambda: logging.disable(old_disable)) + self.assertEqual(old_disable, 0) + self.addCleanup(logging.disable, old_disable) logging.disable(83) self.assertEqual(logging.root.manager.disable, 83) @@ -3266,7 +3265,7 @@ def test_level(self): old_level = logging.root.level - self.addCleanup(lambda: logging.root.setLevel(old_level)) + self.addCleanup(logging.root.setLevel, old_level) logging.basicConfig(level=57) self.assertEqual(logging.root.level, 57) @@ -3311,7 +3310,7 @@ old_basic_config() old_level = logging.root.level logging.root.setLevel(100) # avoid having messages in stderr - self.addCleanup(lambda: logging.root.setLevel(old_level)) + self.addCleanup(logging.root.setLevel, old_level) called.append((a, kw)) patch(self, logging, 'basicConfig', my_basic_config) @@ -3353,7 +3352,7 @@ self.recording = RecordingHandler() self.logger = logging.root self.logger.addHandler(self.recording) - self.addCleanup(lambda: self.logger.removeHandler(self.recording)) + self.addCleanup(self.logger.removeHandler, self.recording) self.addCleanup(self.recording.close) def cleanup(): @@ -3367,8 +3366,8 @@ msg = 'testing exception: %r' exc = None try: - assert False - except AssertionError as e: + 1 / 0 + except ZeroDivisionError as e: exc = e self.adapter.exception(msg, self.recording) @@ -3393,8 +3392,8 @@ def test_is_enabled_for(self): old_disable = self.adapter.logger.manager.disable self.adapter.logger.manager.disable = 33 - self.addCleanup(lambda: setattr(self.adapter.logger.manager, - 'disable', old_disable)) + self.addCleanup(setattr, self.adapter.logger.manager, 'disable', + old_disable) self.assertFalse(self.adapter.isEnabledFor(32)) def test_has_handlers(self): @@ -3402,8 +3401,8 @@ for handler in self.logger.handlers: self.logger.removeHandler(handler) - assert not self.logger.hasHandlers() - + + self.assertFalse(self.logger.hasHandlers()) self.assertFalse(self.adapter.hasHandlers()) @@ -3414,7 +3413,7 @@ self.recording = RecordingHandler() self.logger = logging.Logger(name='blah') self.logger.addHandler(self.recording) - self.addCleanup(lambda: self.logger.removeHandler(self.recording)) + self.addCleanup(self.logger.removeHandler, self.recording) self.addCleanup(self.recording.close) self.addCleanup(logging.shutdown) @@ -3425,8 +3424,8 @@ msg = 'testing exception: %r' exc = None try: - assert False - except AssertionError as e: + 1 / 0 + except ZeroDivisionError as e: exc = e self.logger.exception(msg, self.recording) @@ -3440,14 +3439,14 @@ def test_log_invalid_level_with_raise(self): old_raise = logging.raiseExceptions - self.addCleanup(lambda: setattr(logging, 'raiseExecptions', old_raise)) + self.addCleanup(setattr, logging, 'raiseExecptions', old_raise) logging.raiseExceptions = True self.assertRaises(TypeError, self.logger.log, '10', 'test message') def test_log_invalid_level_no_raise(self): old_raise = logging.raiseExceptions - self.addCleanup(lambda: setattr(logging, 'raiseExecptions', old_raise)) + self.addCleanup(setattr, logging, 'raiseExecptions', old_raise) logging.raiseExceptions = False self.logger.log('10', 'test message') # no exception happens @@ -3489,22 +3488,17 @@ for handler in self.logger.handlers: self.logger.removeHandler(handler) - assert not self.logger.hasHandlers() - self.assertFalse(self.logger.hasHandlers()) def test_has_handlers_no_propagate(self): child_logger = logging.getLogger('blah.child') child_logger.propagate = False - assert child_logger.handlers == [] - self.assertFalse(child_logger.hasHandlers()) def test_is_enabled_for(self): old_disable = self.logger.manager.disable self.logger.manager.disable = 23 - self.addCleanup(lambda: setattr(self.logger.manager, - 'disable', old_disable)) + self.addCleanup(setattr, self.logger.manager, 'disable', old_disable) self.assertFalse(self.logger.isEnabledFor(22)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 11:00:30 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 11:00:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_Do_not_add_txt_?= =?utf8?q?files_twice=2E?= Message-ID: http://hg.python.org/cpython/rev/df7b9c5d6ba1 changeset: 70643:df7b9c5d6ba1 branch: 3.1 parent: 70571:0639e630426c user: Martin v. L?wis date: Sun Jun 05 10:55:57 2011 +0200 summary: Do not add txt files twice. files: Tools/msi/msi.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1021,8 +1021,6 @@ lib.add_file("zipdir.zip") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") - if dir=='cjkencodings': - lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='output': -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 11:00:31 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 11:00:31 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4xKTogQWRkIDMuMS40IFVV?= =?utf8?q?IDs=2E?= Message-ID: http://hg.python.org/cpython/rev/d4a99fb5c2c5 changeset: 70644:d4a99fb5c2c5 branch: 3.1 user: Martin v. L?wis date: Sun Jun 05 10:56:44 2011 +0200 summary: Add 3.1.4 UUIDs. files: Tools/msi/uuids.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py --- a/Tools/msi/uuids.py +++ b/Tools/msi/uuids.py @@ -80,4 +80,6 @@ '3.1.3121':'{a1e436f8-92fc-4ddb-af18-a12529c57aaf}', # 3.1.3rc1 '3.1.3122':'{2fc19026-a3e5-493e-92a0-c1f3b4a272ae}', # 3.1.3rc2 '3.1.3150':'{f719d8a6-46fc-4d71-94c6-ffd17a8c9f35}', # 3.1.3 + '3.1.4121':'{3921EAA3-08F4-4e9b-A42B-0BFC9C3D13F8}', # 3.1.4rc1 + '3.1.4150':'{1ACA3135-BA08-41a9-8019-9BFA2BD1C4EE}', # 3.1.4 } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:44:16 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 19:44:16 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge=3ADo_not_add_txt_files_twice?= Message-ID: http://hg.python.org/cpython/rev/83ceb26e084e changeset: 70645:83ceb26e084e branch: 3.2 parent: 70628:8572bf1b56ec parent: 70643:df7b9c5d6ba1 user: Martin v. L?wis date: Sun Jun 05 19:42:21 2011 +0200 summary: merge:Do not add txt files twice files: Tools/msi/msi.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1031,8 +1031,6 @@ lib.glob("*.0") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") - if dir=='cjkencodings': - lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='xmltestdata': -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:44:16 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 19:44:16 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_null_merge?= Message-ID: http://hg.python.org/cpython/rev/52405ec0c8d1 changeset: 70646:52405ec0c8d1 branch: 3.2 parent: 70645:83ceb26e084e parent: 70644:d4a99fb5c2c5 user: Martin v. L?wis date: Sun Jun 05 19:43:03 2011 +0200 summary: null merge files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:44:17 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 19:44:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge=3ADo_not_add_txt_files_twice?= Message-ID: http://hg.python.org/cpython/rev/e2a2811ec9e8 changeset: 70647:e2a2811ec9e8 parent: 70642:44139ece7a31 parent: 70646:52405ec0c8d1 user: Martin v. L?wis date: Sun Jun 05 19:43:56 2011 +0200 summary: merge:Do not add txt files twice files: Tools/msi/msi.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1031,8 +1031,6 @@ lib.glob("*.0") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") - if dir=='cjkencodings': - lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='xmltestdata': -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:51:05 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 05 Jun 2011 19:51:05 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogQWRkIDIuNy4yIFVV?= =?utf8?q?IDs?= Message-ID: http://hg.python.org/cpython/rev/f4dd7478dc35 changeset: 70648:f4dd7478dc35 branch: 2.7 parent: 70623:42fd2d1fc58d user: Martin v. L?wis date: Sun Jun 05 10:43:45 2011 +0200 summary: Add 2.7.2 UUIDs files: Tools/msi/uuids.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py --- a/Tools/msi/uuids.py +++ b/Tools/msi/uuids.py @@ -53,4 +53,6 @@ '2.7.1121':'{60a4036a-374c-4fd2-84b9-bfae7db03931}', # 2.7.1rc1 '2.7.1122':'{5965e7d1-5584-4de9-b13a-694e0b2ee3a6}', # 2.7.1rc2 '2.7.1150':'{32939827-d8e5-470a-b126-870db3c69fdf}', # 2.7.1 + '2.7.2121':'{B2E1F06E-F719-4786-972A-488A336EB2A0}', # 2.7.2rc1 + '2.7.2150':'{2E295B5B-1AD4-4d36-97C2-A316084722CF}', # 2.7.2 } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:51:06 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 05 Jun 2011 19:51:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Stop_adding_txt?= =?utf8?q?_files_twice=2E?= Message-ID: http://hg.python.org/cpython/rev/9562cbf41b81 changeset: 70649:9562cbf41b81 branch: 2.7 user: Martin v. L?wis date: Sun Jun 05 10:44:18 2011 +0200 summary: Stop adding txt files twice. files: Tools/msi/msi.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1022,8 +1022,6 @@ lib.add_file("zipdir.zip") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") - if dir=='cjkencodings': - lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='xmltestdata': -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 19:51:06 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 05 Jun 2011 19:51:06 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_2=2E7=2E2_release_branch?= Message-ID: http://hg.python.org/cpython/rev/6a4b67e85309 changeset: 70650:6a4b67e85309 branch: 2.7 parent: 70637:78d79499e7de parent: 70649:9562cbf41b81 user: Benjamin Peterson date: Sun Jun 05 12:51:18 2011 -0500 summary: merge 2.7.2 release branch files: Tools/msi/msi.py | 2 -- Tools/msi/uuids.py | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1022,8 +1022,6 @@ lib.add_file("zipdir.zip") if dir=='tests' and parent.physical=='distutils': lib.add_file("Setup.sample") - if dir=='cjkencodings': - lib.glob("*.txt") if dir=='decimaltestdata': lib.glob("*.decTest") if dir=='xmltestdata': diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py --- a/Tools/msi/uuids.py +++ b/Tools/msi/uuids.py @@ -53,4 +53,6 @@ '2.7.1121':'{60a4036a-374c-4fd2-84b9-bfae7db03931}', # 2.7.1rc1 '2.7.1122':'{5965e7d1-5584-4de9-b13a-694e0b2ee3a6}', # 2.7.1rc2 '2.7.1150':'{32939827-d8e5-470a-b126-870db3c69fdf}', # 2.7.1 + '2.7.2121':'{B2E1F06E-F719-4786-972A-488A336EB2A0}', # 2.7.2rc1 + '2.7.2150':'{2E295B5B-1AD4-4d36-97C2-A316084722CF}', # 2.7.2 } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 5 20:43:40 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 05 Jun 2011 20:43:40 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Drop_old_UUIDs=2E?= Message-ID: http://hg.python.org/cpython/rev/7323a865457a changeset: 70651:7323a865457a parent: 70647:e2a2811ec9e8 user: Martin v. L?wis date: Sun Jun 05 20:43:30 2011 +0200 summary: Drop old UUIDs. files: Tools/msi/uuids.py | 60 ---------------------------------- 1 files changed, 0 insertions(+), 60 deletions(-) diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py --- a/Tools/msi/uuids.py +++ b/Tools/msi/uuids.py @@ -7,66 +7,6 @@ # generated. For official releases, we record the product codes, # so people can refer to them. product_codes = { - '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1 - '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2 - '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 - '2.5.111': '{c797ecf8-a8e6-4fec-bb99-526b65f28626}', # 2.5b1 - '2.5.112': '{32beb774-f625-439d-b587-7187487baf15}', # 2.5b2 - '2.5.113': '{89f23918-11cf-4f08-be13-b9b2e6463fd9}', # 2.5b3 - '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1 - '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2 - '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0 - '2.5.1121':'{0378b43e-6184-4c2f-be1a-4a367781cd54}', # 2.5.1c1 - '2.5.1150':'{31800004-6386-4999-a519-518f2d78d8f0}', # 2.5.1 - '2.5.2150':'{6304a7da-1132-4e91-a343-a296269eab8a}', # 2.5.2c1 - '2.5.2150':'{6b976adf-8ae8-434e-b282-a06c7f624d2f}', # 2.5.2 - '2.6.101': '{0ba82e1b-52fd-4e03-8610-a6c76238e8a8}', # 2.6a1 - '2.6.102': '{3b27e16c-56db-4570-a2d3-e9a26180c60b}', # 2.6a2 - '2.6.103': '{cd06a9c5-bde5-4bd7-9874-48933997122a}', # 2.6a3 - '2.6.104': '{dc6ed634-474a-4a50-a547-8de4b7491e53}', # 2.6a4 - '2.6.111': '{3f82079a-5bee-4c4a-8a41-8292389e24ae}', # 2.6b1 - '2.6.112': '{8a0e5970-f3e6-4737-9a2b-bc5ff0f15fb5}', # 2.6b2 - '2.6.113': '{df4f5c21-6fcc-4540-95de-85feba634e76}', # 2.6b3 - '2.6.121': '{bbd34464-ddeb-4028-99e5-f16c4a8fbdb3}', # 2.6c1 - '2.6.122': '{8f64787e-a023-4c60-bfee-25d3a3f592c6}', # 2.6c2 - '2.6.150': '{110eb5c4-e995-4cfb-ab80-a5f315bea9e8}', # 2.6.0 - '2.6.1150':'{9cc89170-000b-457d-91f1-53691f85b223}', # 2.6.1 - '2.6.2121':'{adac412b-b209-4c15-b6ab-dca1b6e47144}', # 2.6.2c1 - '2.6.2150':'{24aab420-4e30-4496-9739-3e216f3de6ae}', # 2.6.2 - '2.6.3121':'{a73e0254-dcda-4fe4-bf37-c7e1c4f4ebb6}', # 2.6.3c1 - '2.6.3150':'{3d9ac095-e115-4e94-bdef-7f7edf17697d}', # 2.6.3 - '2.6.4121':'{727de605-0359-4606-a94b-c2033652379b}', # 2.6.4c1 - '2.6.4122':'{4f7603c6-6352-4299-a398-150a31b19acc}', # 2.6.4c2 - '2.6.4150':'{e7394a0f-3f80-45b1-87fc-abcd51893246}', # 2.6.4 - '2.6.5121':'{e0e273d7-7598-4701-8325-c90c069fd5ff}', # 2.6.5c1 - '2.6.5122':'{fa227b76-0671-4dc6-b826-c2ff2a70dfd5}', # 2.6.5c2 - '2.6.5150':'{4723f199-fa64-4233-8e6e-9fccc95a18ee}', # 2.6.5 - '2.7.101': '{eca1bbef-432c-49ae-a667-c213cc7bbf22}', # 2.7a1 - '2.7.102': '{21ce16ed-73c4-460d-9b11-522f417b2090}', # 2.7a2 - '2.7.103': '{6e7dbd55-ba4a-48ac-a688-6c75db4d7500}', # 2.7a3 - '2.7.104': '{ee774ba3-74a5-48d9-b425-b35a287260c8}', # 2.7a4 - '2.7.111': '{9cfd9ec7-a9c7-4980-a1c6-054fc6493eb3}', # 2.7b1 - '2.7.112': '{9a72faf6-c304-4165-8595-9291ff30cac6}', # 2.7b2 - '2.7.121': '{f530c94a-dd53-4de9-948e-b632b9cb48d2}', # 2.7c1 - '2.7.122': '{f80905d2-dd8d-4b8e-8a40-c23c93dca07d}', # 2.7c2 - '2.7.150': '{20c31435-2a0a-4580-be8b-ac06fc243ca4}', # 2.7.0 - '3.0.101': '{8554263a-3242-4857-9359-aa87bc2c58c2}', # 3.0a1 - '3.0.102': '{692d6e2c-f0ac-40b8-a133-7191aeeb67f9}', # 3.0a2 - '3.0.103': '{49cb2995-751a-4753-be7a-d0b1bb585e06}', # 3.0a3 - '3.0.104': '{87cb019e-19fd-4238-b1c7-85751437d646}', # 3.0a4 - '3.0.105': '{cf2659af-19ec-43d2-8c35-0f6a09439d42}', # 3.0a5 - '3.0.111': '{36c26f55-837d-45cf-848c-5f5c0fb47a28}', # 3.0b1 - '3.0.112': '{056a0fbc-c8fe-4c61-aade-c4411b70c998}', # 3.0b2 - '3.0.113': '{2b2e89a9-83af-43f9-b7d5-96e80c5a3f26}', # 3.0b3 - '3.0.114': '{e95c31af-69be-4dd7-96e6-e5fc85e660e6}', # 3.0b4 - '3.0.121': '{d0979c5e-cd3c-42ec-be4c-e294da793573}', # 3.0c1 - '3.0.122': '{f707b8e9-a257-4045-818e-4923fc20fbb6}', # 3.0c2 - '3.0.123': '{5e7208f1-8643-4ea2-ab5e-4644887112e3}', # 3.0c3 - '3.0.150': '{e0e56e21-55de-4f77-a109-1baa72348743}', # 3.0.0 - '3.0.1121':'{d35b1ea5-3d70-4872-bf7e-cd066a77a9c9}', # 3.0.1c1 - '3.0.1150':'{de2f2d9c-53e2-40ee-8209-74da63cb060e}', # 3.0.1 - '3.0.2121':'{cef79e7f-9809-49e2-afd2-e24148d7c855}', # 3.0.2c1 - '3.0.2150':'{0cf3b95a-8382-4607-9779-c36407ff362c}', # 3.0.2 '3.1.101': '{c423eada-c498-4d51-9eb4-bfeae647e0a0}', # 3.1a1 '3.1.102': '{f6e199bf-dc64-42f3-87d4-1525991a013e}', # 3.1a2 '3.1.111': '{c3c82893-69b2-4676-8554-1b6ee6c191e9}', # 3.1b1 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 05:05:09 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 06 Jun 2011 05:05:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_greatly_improve_argument_pa?= =?utf8?q?rsing_error_messages_=28closes_=2312265=29?= Message-ID: http://hg.python.org/cpython/rev/44d46d74ef4f changeset: 70652:44d46d74ef4f parent: 70647:e2a2811ec9e8 user: Benjamin Peterson date: Sun Jun 05 22:04:07 2011 -0500 summary: greatly improve argument parsing error messages (closes #12265) files: Lib/inspect.py | 109 +++--- Lib/test/test_extcall.py | 82 ++++- Lib/test/test_keywordonlyarg.py | 2 +- Misc/NEWS | 3 + Python/ceval.c | 309 ++++++++++--------- 5 files changed, 304 insertions(+), 201 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -914,6 +914,29 @@ specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) return '(' + ', '.join(specs) + ')' +def _positional_error(f_name, args, kwonly, varargs, defcount, given, values): + atleast = len(args) - defcount + if given is None: + given = len([arg for arg in args if arg in values]) + kwonly_given = len([arg for arg in kwonly if arg in values]) + if varargs: + plural = atleast != 1 + sig = "at least %d" % (atleast,) + elif defcount: + plural = True + sig = "from %d to %d" % (atleast, len(args)) + else: + plural = len(args) != 1 + sig = str(len(args)) + kwonly_sig = "" + if kwonly_given: + msg = " positional argument%s (and %d keyword-only argument%s)" + kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given, + "s" if kwonly_given != 1 else "")) + raise TypeError("%s() takes %s positional argument%s but %d%s %s given" % + (f_name, sig, "s" if plural else "", given, kwonly_sig, + "was" if given == 1 and not kwonly_given else "were")) + def getcallargs(func, *positional, **named): """Get the mapping of arguments to values. @@ -925,64 +948,50 @@ f_name = func.__name__ arg2value = {} + if ismethod(func) and func.__self__ is not None: # implicit 'self' (or 'cls' for classmethods) argument positional = (func.__self__,) + positional num_pos = len(positional) - num_total = num_pos + len(named) num_args = len(args) num_defaults = len(defaults) if defaults else 0 - for arg, value in zip(args, positional): - arg2value[arg] = value + + n = min(num_pos, num_args) + for i in range(n): + arg2value[args[i]] = positional[i] if varargs: - if num_pos > num_args: - arg2value[varargs] = positional[-(num_pos-num_args):] - else: - arg2value[varargs] = () - elif 0 < num_args < num_pos: - raise TypeError('%s() takes %s %d positional %s (%d given)' % ( - f_name, 'at most' if defaults else 'exactly', num_args, - 'arguments' if num_args > 1 else 'argument', num_total)) - elif num_args == 0 and num_total: - if varkw or kwonlyargs: - if num_pos: - # XXX: We should use num_pos, but Python also uses num_total: - raise TypeError('%s() takes exactly 0 positional arguments ' - '(%d given)' % (f_name, num_total)) - else: - raise TypeError('%s() takes no arguments (%d given)' % - (f_name, num_total)) - - for arg in itertools.chain(args, kwonlyargs): - if arg in named: - if arg in arg2value: - raise TypeError("%s() got multiple values for keyword " - "argument '%s'" % (f_name, arg)) - else: - arg2value[arg] = named.pop(arg) - for kwonlyarg in kwonlyargs: - if kwonlyarg not in arg2value: - try: - arg2value[kwonlyarg] = kwonlydefaults[kwonlyarg] - except KeyError: - raise TypeError("%s() needs keyword-only argument %s" % - (f_name, kwonlyarg)) - if defaults: # fill in any missing values with the defaults - for arg, value in zip(args[-num_defaults:], defaults): + arg2value[varargs] = tuple(positional[n:]) + possible_kwargs = set(args + kwonlyargs) + if varkw: + arg2value[varkw] = {} + for kw, value in named.items(): + if kw not in possible_kwargs: + if not varkw: + raise TypeError("%s() got an unexpected keyword argument %r" % + (f_name, kw)) + arg2value[varkw][kw] = value + continue + if kw in arg2value: + raise TypeError("%s() got multiple values for argument %r" % + (f_name, kw)) + arg2value[kw] = value + if num_pos > num_args and not varargs: + _positional_error(f_name, args, kwonlyargs, varargs, num_defaults, + num_pos, arg2value) + if num_pos < num_args: + for arg in args[:num_args - num_defaults]: if arg not in arg2value: - arg2value[arg] = value - if varkw: - arg2value[varkw] = named - elif named: - unexpected = next(iter(named)) - raise TypeError("%s() got an unexpected keyword argument '%s'" % - (f_name, unexpected)) - unassigned = num_args - len([arg for arg in args if arg in arg2value]) - if unassigned: - num_required = num_args - num_defaults - raise TypeError('%s() takes %s %d %s (%d given)' % ( - f_name, 'at least' if defaults else 'exactly', num_required, - 'arguments' if num_required > 1 else 'argument', num_total)) + _positional_error(f_name, args, kwonlyargs, varargs, + num_defaults, None, arg2value) + for i, arg in enumerate(args[num_args - num_defaults:]): + if arg not in arg2value: + arg2value[arg] = defaults[i] + for kwarg in kwonlyargs: + if kwarg not in arg2value: + if kwarg not in kwonlydefaults: + raise TypeError("%s() requires keyword-only argument %r" % + (f_name, kwarg)) + arg2value[kwarg] = kwonlydefaults[kwarg] return arg2value # -------------------------------------------------- stack frame extraction diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -66,17 +66,17 @@ >>> g() Traceback (most recent call last): ... - TypeError: g() takes at least 1 argument (0 given) + TypeError: g() takes at least 1 positional argument but 0 were given >>> g(*()) Traceback (most recent call last): ... - TypeError: g() takes at least 1 argument (0 given) + TypeError: g() takes at least 1 positional argument but 0 were given >>> g(*(), **{}) Traceback (most recent call last): ... - TypeError: g() takes at least 1 argument (0 given) + TypeError: g() takes at least 1 positional argument but 0 were given >>> g(1) 1 () {} @@ -151,7 +151,7 @@ >>> g(1, 2, 3, **{'x': 4, 'y': 5}) Traceback (most recent call last): ... - TypeError: g() got multiple values for keyword argument 'x' + TypeError: g() got multiple values for argument 'x' >>> f(**{1:2}) Traceback (most recent call last): @@ -263,29 +263,91 @@ >>> f(**x) 1 2 -A obscure message: +Some additional tests about positional argument errors: >>> def f(a, b): ... pass >>> f(b=1) Traceback (most recent call last): ... - TypeError: f() takes exactly 2 arguments (1 given) - -The number of arguments passed in includes keywords: + TypeError: f() takes 2 positional arguments but 1 was given >>> def f(a): ... pass >>> f(6, a=4, *(1, 2, 3)) Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (5 given) + TypeError: f() got multiple values for argument 'a' >>> def f(a, *, kw): ... pass >>> f(6, 4, kw=4) Traceback (most recent call last): ... - TypeError: f() takes exactly 1 positional argument (3 given) + TypeError: f() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given + + >>> def f(a): + ... pass + >>> f() + Traceback (most recent call last): + ... + TypeError: f() takes 1 positional argument but 0 were given + + >>> def f(a, b): + ... pass + >>> f(1) + Traceback (most recent call last): + ... + TypeError: f() takes 2 positional arguments but 1 was given + + >>> def f(a, *b): + ... pass + >>> f() + Traceback (most recent call last): + ... + TypeError: f() takes at least 1 positional argument but 0 were given + + >>> def f(a, *, kw=4): + ... pass + >>> f(kw=4) + Traceback (most recent call last): + ... + TypeError: f() takes 1 positional argument but 0 positional arguments (and 1 keyword-only argument) were given + + >>> def f(a, b=2): + ... pass + >>> f() + Traceback (most recent call last): + ... + TypeError: f() takes from 1 to 2 positional arguments but 0 were given + + >>> def f(a, *b): + ... pass + >>> f() + Traceback (most recent call last): + ... + TypeError: f() takes at least 1 positional argument but 0 were given + + >>> def f(*, kw): + ... pass + >>> f(3, kw=4) + Traceback (most recent call last): + ... + TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given + + >>> def f(a, c=3, *b, kw): + ... pass + >>> f() + Traceback (most recent call last): + ... + TypeError: f() takes at least 1 positional argument but 0 were given + >>> f(kw=3) + Traceback (most recent call last): + ... + TypeError: f() takes at least 1 positional argument but 0 positional arguments (and 1 keyword-only argument) were given + >>> f(kw=3, c=4) + Traceback (most recent call last): + ... + TypeError: f() takes at least 1 positional argument but 1 positional argument (and 1 keyword-only argument) were given """ import sys diff --git a/Lib/test/test_keywordonlyarg.py b/Lib/test/test_keywordonlyarg.py --- a/Lib/test/test_keywordonlyarg.py +++ b/Lib/test/test_keywordonlyarg.py @@ -78,7 +78,7 @@ pass with self.assertRaises(TypeError) as exc: f(1, 2, 3) - expected = "f() takes at most 2 positional arguments (3 given)" + expected = "f() takes from 1 to 2 positional arguments but 3 were given" self.assertEqual(str(exc.exception), expected) def testSyntaxErrorForFunctionCall(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12265: Make error messages produced by passing an invalid set of + arguments to a function more informative. + - Issue #12225: Still allow Python to build if Python is not in its hg repo or mercurial is not installed. diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3045,6 +3045,63 @@ return retval; } +static void +positional_argument_error(PyCodeObject *co, int given, int defcount, PyObject **fastlocals) +{ + int plural; + int kwonly_given = 0; + int atleast = co->co_argcount - defcount; + int i; + PyObject *sig, *kwonly_sig; + + if (given == -1) { + given = 0; + for (i = 0; i < co->co_argcount; i++) + if (GETLOCAL(i)) + given++; + } + for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++) + if (GETLOCAL(i)) + kwonly_given++; + if (co->co_flags & CO_VARARGS) { + plural = atleast != 1; + sig = PyUnicode_FromFormat("at least %d", atleast); + } + else if (defcount) { + plural = 1; + sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount); + } + else { + plural = co->co_argcount != 1; + sig = PyUnicode_FromFormat("%d", co->co_argcount); + } + if (sig == NULL) + return; + if (kwonly_given) { + const char *format = " positional argument%s (and %d keyword-only argument%s)"; + kwonly_sig = PyUnicode_FromFormat(format, given != 1 ? "s" : "", kwonly_given, + kwonly_given != 1 ? "s" : ""); + if (kwonly_sig == NULL) { + Py_DECREF(sig); + return; + } + } + else { + /* This will not fail. */ + kwonly_sig = PyUnicode_FromString(""); + } + PyErr_Format(PyExc_TypeError, + "%U() takes %U positional argument%s but %d%U %s given", + co->co_name, + sig, + plural ? "s" : "", + given, + kwonly_sig, + given == 1 && !kwonly_given ? "was" : "were"); + Py_DECREF(sig); + Py_DECREF(kwonly_sig); +} + /* This is gonna seem *real weird*, but if you put some other code between PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust the test in the if statements in Misc/gdbinit (pystack and pystackv). */ @@ -3061,6 +3118,9 @@ PyThreadState *tstate = PyThreadState_GET(); PyObject *x, *u; int total_args = co->co_argcount + co->co_kwonlyargcount; + int i; + int n = argcount; + PyObject *kwdict = NULL; if (globals == NULL) { PyErr_SetString(PyExc_SystemError, @@ -3077,161 +3137,130 @@ fastlocals = f->f_localsplus; freevars = f->f_localsplus + co->co_nlocals; - if (total_args || co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) { - int i; - int n = argcount; - PyObject *kwdict = NULL; - if (co->co_flags & CO_VARKEYWORDS) { - kwdict = PyDict_New(); - if (kwdict == NULL) - goto fail; - i = total_args; - if (co->co_flags & CO_VARARGS) - i++; - SETLOCAL(i, kwdict); - } - if (argcount > co->co_argcount) { - if (!(co->co_flags & CO_VARARGS)) { - PyErr_Format(PyExc_TypeError, - "%U() takes %s %d " - "positional argument%s (%d given)", - co->co_name, - defcount ? "at most" : "exactly", - co->co_argcount, - co->co_argcount == 1 ? "" : "s", - argcount + kwcount); - goto fail; - } - n = co->co_argcount; - } - for (i = 0; i < n; i++) { + /* Parse arguments. */ + if (co->co_flags & CO_VARKEYWORDS) { + kwdict = PyDict_New(); + if (kwdict == NULL) + goto fail; + i = total_args; + if (co->co_flags & CO_VARARGS) + i++; + SETLOCAL(i, kwdict); + } + if (argcount > co->co_argcount) + n = co->co_argcount; + for (i = 0; i < n; i++) { + x = args[i]; + Py_INCREF(x); + SETLOCAL(i, x); + } + if (co->co_flags & CO_VARARGS) { + u = PyTuple_New(argcount - n); + if (u == NULL) + goto fail; + SETLOCAL(total_args, u); + for (i = n; i < argcount; i++) { x = args[i]; Py_INCREF(x); - SETLOCAL(i, x); + PyTuple_SET_ITEM(u, i-n, x); } - if (co->co_flags & CO_VARARGS) { - u = PyTuple_New(argcount - n); - if (u == NULL) + } + for (i = 0; i < kwcount; i++) { + PyObject **co_varnames; + PyObject *keyword = kws[2*i]; + PyObject *value = kws[2*i + 1]; + int j; + if (keyword == NULL || !PyUnicode_Check(keyword)) { + PyErr_Format(PyExc_TypeError, + "%U() keywords must be strings", + co->co_name); + goto fail; + } + /* Speed hack: do raw pointer compares. As names are + normally interned this should almost always hit. */ + co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; + for (j = 0; j < total_args; j++) { + PyObject *nm = co_varnames[j]; + if (nm == keyword) + goto kw_found; + } + /* Slow fallback, just in case */ + for (j = 0; j < total_args; j++) { + PyObject *nm = co_varnames[j]; + int cmp = PyObject_RichCompareBool( + keyword, nm, Py_EQ); + if (cmp > 0) + goto kw_found; + else if (cmp < 0) goto fail; - SETLOCAL(total_args, u); - for (i = n; i < argcount; i++) { - x = args[i]; - Py_INCREF(x); - PyTuple_SET_ITEM(u, i-n, x); - } } - for (i = 0; i < kwcount; i++) { - PyObject **co_varnames; - PyObject *keyword = kws[2*i]; - PyObject *value = kws[2*i + 1]; - int j; - if (keyword == NULL || !PyUnicode_Check(keyword)) { - PyErr_Format(PyExc_TypeError, - "%U() keywords must be strings", - co->co_name); - goto fail; - } - /* Speed hack: do raw pointer compares. As names are - normally interned this should almost always hit. */ - co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item; - for (j = 0; j < total_args; j++) { - PyObject *nm = co_varnames[j]; - if (nm == keyword) - goto kw_found; - } - /* Slow fallback, just in case */ - for (j = 0; j < total_args; j++) { - PyObject *nm = co_varnames[j]; - int cmp = PyObject_RichCompareBool( - keyword, nm, Py_EQ); - if (cmp > 0) - goto kw_found; - else if (cmp < 0) - goto fail; - } - if (j >= total_args && kwdict == NULL) { - PyErr_Format(PyExc_TypeError, - "%U() got an unexpected " - "keyword argument '%S'", - co->co_name, - keyword); - goto fail; - } - PyDict_SetItem(kwdict, keyword, value); - continue; - kw_found: - if (GETLOCAL(j) != NULL) { - PyErr_Format(PyExc_TypeError, - "%U() got multiple " - "values for keyword " - "argument '%S'", + if (j >= total_args && kwdict == NULL) { + PyErr_Format(PyExc_TypeError, + "%U() got an unexpected " + "keyword argument '%S'", co->co_name, keyword); - goto fail; - } - Py_INCREF(value); - SETLOCAL(j, value); + goto fail; } - if (co->co_kwonlyargcount > 0) { - for (i = co->co_argcount; i < total_args; i++) { - PyObject *name; - if (GETLOCAL(i) != NULL) - continue; - name = PyTuple_GET_ITEM(co->co_varnames, i); - if (kwdefs != NULL) { - PyObject *def = PyDict_GetItem(kwdefs, name); - if (def) { - Py_INCREF(def); - SETLOCAL(i, def); - continue; - } - } - PyErr_Format(PyExc_TypeError, - "%U() needs keyword-only argument %S", - co->co_name, name); + PyDict_SetItem(kwdict, keyword, value); + continue; + kw_found: + if (GETLOCAL(j) != NULL) { + PyErr_Format(PyExc_TypeError, + "%U() got multiple " + "values for argument '%S'", + co->co_name, + keyword); + goto fail; + } + Py_INCREF(value); + SETLOCAL(j, value); + } + if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { + positional_argument_error(co, argcount, defcount, fastlocals); + goto fail; + } + if (argcount < co->co_argcount) { + int m = co->co_argcount - defcount; + for (i = argcount; i < m; i++) { + if (GETLOCAL(i) == NULL) { + positional_argument_error(co, -1, defcount, fastlocals); goto fail; } } - if (argcount < co->co_argcount) { - int m = co->co_argcount - defcount; - for (i = argcount; i < m; i++) { - if (GETLOCAL(i) == NULL) { - int j, given = 0; - for (j = 0; j < co->co_argcount; j++) - if (GETLOCAL(j)) - given++; - PyErr_Format(PyExc_TypeError, - "%U() takes %s %d " - "argument%s " - "(%d given)", - co->co_name, - ((co->co_flags & CO_VARARGS) || - defcount) ? "at least" - : "exactly", - m, m == 1 ? "" : "s", given); - goto fail; - } - } - if (n > m) - i = n - m; - else - i = 0; - for (; i < defcount; i++) { - if (GETLOCAL(m+i) == NULL) { - PyObject *def = defs[i]; - Py_INCREF(def); - SETLOCAL(m+i, def); - } + if (n > m) + i = n - m; + else + i = 0; + for (; i < defcount; i++) { + if (GETLOCAL(m+i) == NULL) { + PyObject *def = defs[i]; + Py_INCREF(def); + SETLOCAL(m+i, def); } } } - else if (argcount > 0 || kwcount > 0) { - PyErr_Format(PyExc_TypeError, - "%U() takes no arguments (%d given)", - co->co_name, - argcount + kwcount); - goto fail; + if (co->co_kwonlyargcount > 0) { + for (i = co->co_argcount; i < total_args; i++) { + PyObject *name; + if (GETLOCAL(i) != NULL) + continue; + name = PyTuple_GET_ITEM(co->co_varnames, i); + if (kwdefs != NULL) { + PyObject *def = PyDict_GetItem(kwdefs, name); + if (def) { + Py_INCREF(def); + SETLOCAL(i, def); + continue; + } + } + PyErr_Format(PyExc_TypeError, + "%U() requires keyword-only argument '%S'", + co->co_name, name); + goto fail; + } } + /* Allocate and initialize storage for cell vars, and copy free vars into frame. This isn't too efficient right now. */ if (PyTuple_GET_SIZE(co->co_cellvars)) { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 05:05:09 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 06 Jun 2011 05:05:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/d3c30f9fe3e8 changeset: 70653:d3c30f9fe3e8 parent: 70652:44d46d74ef4f parent: 70651:7323a865457a user: Benjamin Peterson date: Sun Jun 05 22:05:22 2011 -0500 summary: merge heads files: Tools/msi/uuids.py | 60 ---------------------------------- 1 files changed, 0 insertions(+), 60 deletions(-) diff --git a/Tools/msi/uuids.py b/Tools/msi/uuids.py --- a/Tools/msi/uuids.py +++ b/Tools/msi/uuids.py @@ -7,66 +7,6 @@ # generated. For official releases, we record the product codes, # so people can refer to them. product_codes = { - '2.5.101': '{bc14ce3e-5e72-4a64-ac1f-bf59a571898c}', # 2.5a1 - '2.5.102': '{5eed51c1-8e9d-4071-94c5-b40de5d49ba5}', # 2.5a2 - '2.5.103': '{73dcd966-ffec-415f-bb39-8342c1f47017}', # 2.5a3 - '2.5.111': '{c797ecf8-a8e6-4fec-bb99-526b65f28626}', # 2.5b1 - '2.5.112': '{32beb774-f625-439d-b587-7187487baf15}', # 2.5b2 - '2.5.113': '{89f23918-11cf-4f08-be13-b9b2e6463fd9}', # 2.5b3 - '2.5.121': '{8e9321bc-6b24-48a3-8fd4-c95f8e531e5f}', # 2.5c1 - '2.5.122': '{a6cd508d-9599-45da-a441-cbffa9f7e070}', # 2.5c2 - '2.5.150': '{0a2c5854-557e-48c8-835a-3b9f074bdcaa}', # 2.5.0 - '2.5.1121':'{0378b43e-6184-4c2f-be1a-4a367781cd54}', # 2.5.1c1 - '2.5.1150':'{31800004-6386-4999-a519-518f2d78d8f0}', # 2.5.1 - '2.5.2150':'{6304a7da-1132-4e91-a343-a296269eab8a}', # 2.5.2c1 - '2.5.2150':'{6b976adf-8ae8-434e-b282-a06c7f624d2f}', # 2.5.2 - '2.6.101': '{0ba82e1b-52fd-4e03-8610-a6c76238e8a8}', # 2.6a1 - '2.6.102': '{3b27e16c-56db-4570-a2d3-e9a26180c60b}', # 2.6a2 - '2.6.103': '{cd06a9c5-bde5-4bd7-9874-48933997122a}', # 2.6a3 - '2.6.104': '{dc6ed634-474a-4a50-a547-8de4b7491e53}', # 2.6a4 - '2.6.111': '{3f82079a-5bee-4c4a-8a41-8292389e24ae}', # 2.6b1 - '2.6.112': '{8a0e5970-f3e6-4737-9a2b-bc5ff0f15fb5}', # 2.6b2 - '2.6.113': '{df4f5c21-6fcc-4540-95de-85feba634e76}', # 2.6b3 - '2.6.121': '{bbd34464-ddeb-4028-99e5-f16c4a8fbdb3}', # 2.6c1 - '2.6.122': '{8f64787e-a023-4c60-bfee-25d3a3f592c6}', # 2.6c2 - '2.6.150': '{110eb5c4-e995-4cfb-ab80-a5f315bea9e8}', # 2.6.0 - '2.6.1150':'{9cc89170-000b-457d-91f1-53691f85b223}', # 2.6.1 - '2.6.2121':'{adac412b-b209-4c15-b6ab-dca1b6e47144}', # 2.6.2c1 - '2.6.2150':'{24aab420-4e30-4496-9739-3e216f3de6ae}', # 2.6.2 - '2.6.3121':'{a73e0254-dcda-4fe4-bf37-c7e1c4f4ebb6}', # 2.6.3c1 - '2.6.3150':'{3d9ac095-e115-4e94-bdef-7f7edf17697d}', # 2.6.3 - '2.6.4121':'{727de605-0359-4606-a94b-c2033652379b}', # 2.6.4c1 - '2.6.4122':'{4f7603c6-6352-4299-a398-150a31b19acc}', # 2.6.4c2 - '2.6.4150':'{e7394a0f-3f80-45b1-87fc-abcd51893246}', # 2.6.4 - '2.6.5121':'{e0e273d7-7598-4701-8325-c90c069fd5ff}', # 2.6.5c1 - '2.6.5122':'{fa227b76-0671-4dc6-b826-c2ff2a70dfd5}', # 2.6.5c2 - '2.6.5150':'{4723f199-fa64-4233-8e6e-9fccc95a18ee}', # 2.6.5 - '2.7.101': '{eca1bbef-432c-49ae-a667-c213cc7bbf22}', # 2.7a1 - '2.7.102': '{21ce16ed-73c4-460d-9b11-522f417b2090}', # 2.7a2 - '2.7.103': '{6e7dbd55-ba4a-48ac-a688-6c75db4d7500}', # 2.7a3 - '2.7.104': '{ee774ba3-74a5-48d9-b425-b35a287260c8}', # 2.7a4 - '2.7.111': '{9cfd9ec7-a9c7-4980-a1c6-054fc6493eb3}', # 2.7b1 - '2.7.112': '{9a72faf6-c304-4165-8595-9291ff30cac6}', # 2.7b2 - '2.7.121': '{f530c94a-dd53-4de9-948e-b632b9cb48d2}', # 2.7c1 - '2.7.122': '{f80905d2-dd8d-4b8e-8a40-c23c93dca07d}', # 2.7c2 - '2.7.150': '{20c31435-2a0a-4580-be8b-ac06fc243ca4}', # 2.7.0 - '3.0.101': '{8554263a-3242-4857-9359-aa87bc2c58c2}', # 3.0a1 - '3.0.102': '{692d6e2c-f0ac-40b8-a133-7191aeeb67f9}', # 3.0a2 - '3.0.103': '{49cb2995-751a-4753-be7a-d0b1bb585e06}', # 3.0a3 - '3.0.104': '{87cb019e-19fd-4238-b1c7-85751437d646}', # 3.0a4 - '3.0.105': '{cf2659af-19ec-43d2-8c35-0f6a09439d42}', # 3.0a5 - '3.0.111': '{36c26f55-837d-45cf-848c-5f5c0fb47a28}', # 3.0b1 - '3.0.112': '{056a0fbc-c8fe-4c61-aade-c4411b70c998}', # 3.0b2 - '3.0.113': '{2b2e89a9-83af-43f9-b7d5-96e80c5a3f26}', # 3.0b3 - '3.0.114': '{e95c31af-69be-4dd7-96e6-e5fc85e660e6}', # 3.0b4 - '3.0.121': '{d0979c5e-cd3c-42ec-be4c-e294da793573}', # 3.0c1 - '3.0.122': '{f707b8e9-a257-4045-818e-4923fc20fbb6}', # 3.0c2 - '3.0.123': '{5e7208f1-8643-4ea2-ab5e-4644887112e3}', # 3.0c3 - '3.0.150': '{e0e56e21-55de-4f77-a109-1baa72348743}', # 3.0.0 - '3.0.1121':'{d35b1ea5-3d70-4872-bf7e-cd066a77a9c9}', # 3.0.1c1 - '3.0.1150':'{de2f2d9c-53e2-40ee-8209-74da63cb060e}', # 3.0.1 - '3.0.2121':'{cef79e7f-9809-49e2-afd2-e24148d7c855}', # 3.0.2c1 - '3.0.2150':'{0cf3b95a-8382-4607-9779-c36407ff362c}', # 3.0.2 '3.1.101': '{c423eada-c498-4d51-9eb4-bfeae647e0a0}', # 3.1a1 '3.1.102': '{f6e199bf-dc64-42f3-87d4-1525991a013e}', # 3.1a2 '3.1.111': '{c3c82893-69b2-4676-8554-1b6ee6c191e9}', # 3.1b1 -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Mon Jun 6 05:08:28 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 06 Jun 2011 05:08:28 +0200 Subject: [Python-checkins] Daily reference leaks (7323a865457a): sum=526 Message-ID: results for 7323a865457a on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 test_parser leaked [150, 150, 150] references, sum=450 test_pyexpat leaked [0, -56, -267] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogij7f_E', '-x'] From python-checkins at python.org Mon Jun 6 05:13:46 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 06 Jun 2011 05:13:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_always_clear_parser_error?= Message-ID: http://hg.python.org/cpython/rev/9faa9270457e changeset: 70654:9faa9270457e user: Benjamin Peterson date: Sun Jun 05 22:14:05 2011 -0500 summary: always clear parser error files: Modules/parsermodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -583,8 +583,8 @@ } else { PyParser_SetError(&err); - PyParser_ClearError(&err); } + PyParser_ClearError(&err); } return (res); } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 10:28:04 2011 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 06 Jun 2011 10:28:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Drop_unfounded_claims_about?= =?utf8?q?_performance=2E?= Message-ID: http://hg.python.org/cpython/rev/75dbdbe53bd9 changeset: 70655:75dbdbe53bd9 user: Martin v. L?wis date: Mon Jun 06 10:25:55 2011 +0200 summary: Drop unfounded claims about performance. files: Doc/howto/sockets.rst | 27 +-------------------------- 1 files changed, 1 insertions(+), 26 deletions(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -386,32 +386,6 @@ files. Don't try this on Windows. On Windows, ``select`` works with sockets only. Also note that in C, many of the more advanced socket options are done differently on Windows. In fact, on Windows I usually use threads (which work -very, very well) with my sockets. Face it, if you want any kind of performance, -your code will look very different on Windows than on Unix. +very, very well) with my sockets. -Performance ------------ - -There's no question that the fastest sockets code uses non-blocking sockets and -select to multiplex them. You can put together something that will saturate a -LAN connection without putting any strain on the CPU. The trouble is that an app -written this way can't do much of anything else - it needs to be ready to -shuffle bytes around at all times. - -Assuming that your app is actually supposed to do something more than that, -threading is the optimal solution, (and using non-blocking sockets will be -faster than using blocking sockets). Unfortunately, threading support in Unixes -varies both in API and quality. So the normal Unix solution is to fork a -subprocess to deal with each connection. The overhead for this is significant -(and don't do this on Windows - the overhead of process creation is enormous -there). It also means that unless each subprocess is completely independent, -you'll need to use another form of IPC, say a pipe, or shared memory and -semaphores, to communicate between the parent and child processes. - -Finally, remember that even though blocking sockets are somewhat slower than -non-blocking, in many cases they are the "right" solution. After all, if your -app is driven by the data it receives over a socket, there's not much sense in -complicating the logic just so your app can wait on ``select`` instead of -``recv``. - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 10:28:26 2011 From: python-checkins at python.org (martin.v.loewis) Date: Mon, 06 Jun 2011 10:28:26 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Drop_claim_about_nasty_prob?= =?utf8?q?lem=2E?= Message-ID: http://hg.python.org/cpython/rev/3301a01071f9 changeset: 70656:3301a01071f9 user: Martin v. L?wis date: Mon Jun 06 10:27:56 2011 +0200 summary: Drop claim about nasty problem. It's unclear what this was referring to; most likely, it was about sockets that the application had already closed, in which case it's not a sockets problem, but an application problem. files: Doc/howto/sockets.rst | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -371,12 +371,6 @@ potential_writers list. If it shows up in the writable list, you have a decent chance that it has connected. -One very nasty problem with ``select``: if somewhere in those input lists of -sockets is one which has died a nasty death, the ``select`` will fail. You then -need to loop through every single damn socket in all those lists and do a -``select([sock],[],[],0)`` until you find the bad one. That timeout of 0 means -it won't take long, but it's ugly. - Actually, ``select`` can be handy even with blocking sockets. It's one way of determining whether you will block - the socket returns as readable when there's something in the buffers. However, this still doesn't help with the problem of -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 12:06:41 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 06 Jun 2011 12:06:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312250=3A_modify_?= =?utf8?q?=22make_buildbottest=22_command_line_instead_of_TESTOPTS?= Message-ID: http://hg.python.org/cpython/rev/bab599e4bd09 changeset: 70657:bab599e4bd09 user: Victor Stinner date: Mon Jun 06 12:04:36 2011 +0200 summary: Issue #12250: modify "make buildbottest" command line instead of TESTOPTS Add TESTTIMEOUT variable (default: 3600 seconds). Use TESTTIMEOUT=0 to disable the timeout. *** fix files: Lib/test/regrtest.py | 6 +++--- Makefile.pre.in | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -22,7 +22,8 @@ -h/--help -- print this text and exit --timeout TIMEOUT -- dump the traceback and exit if a test takes more - than TIMEOUT seconds + than TIMEOUT seconds; disabled if TIMEOUT is negative + or equals to zero --wait -- wait for user input, e.g., allow a debugger to be attached Verbosity @@ -420,8 +421,7 @@ sys.exit(1) timeout = float(a) if timeout <= 0: - print("The timeout must be greater than 0", file=sys.stderr) - sys.exit(1) + timeout = None elif o == '--wait': input("Press any key to continue...") else: diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -755,9 +755,10 @@ # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. -TESTOPTS= -l --timeout=3600 $(EXTRATESTOPTS) +TESTOPTS= -l $(EXTRATESTOPTS) TESTPROG= $(srcdir)/Lib/test/regrtest.py TESTPYTHON= $(RUNSHARED) ./$(BUILDPYTHON) -Wd -E -bb $(TESTPYTHONOPTS) +TESTTIMEOUT= 3600 test: all platform -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f -$(TESTPYTHON) $(TESTPROG) $(TESTOPTS) @@ -789,7 +790,7 @@ - at if which pybuildbot.identify >/dev/null 2>&1; then \ pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ fi - $(TESTPYTHON) $(TESTPROG) -uall -rwW $(TESTOPTS) + $(TESTPYTHON) $(TESTPROG) -uall -rwW --timeout=$(TESTTIMEOUT) $(TESTOPTS) QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multibytecodec test_urllib2_localnet test_itertools \ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 12:14:30 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 06 Jun 2011 12:14:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312250=3A_regrtest_?= =?utf8?q?--timeout_displays_a_warning_instead_of_failing_with_an?= Message-ID: http://hg.python.org/cpython/rev/7ffc5ececcb3 changeset: 70658:7ffc5ececcb3 user: Victor Stinner date: Mon Jun 06 12:14:23 2011 +0200 summary: Issue #12250: regrtest --timeout displays a warning instead of failing with an error if faulthandler.dump_tracebacks_later() is missing (e.g. if Python is compiled without threads). files: Lib/test/regrtest.py | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -415,12 +415,13 @@ # join it with the saved CWD so it ends up where the user expects. testdir = os.path.join(support.SAVEDCWD, a) elif o == '--timeout': - if not hasattr(faulthandler, 'dump_tracebacks_later'): - print("The timeout option requires " - "faulthandler.dump_tracebacks_later", file=sys.stderr) - sys.exit(1) - timeout = float(a) - if timeout <= 0: + if hasattr(faulthandler, 'dump_tracebacks_later'): + timeout = float(a) + if timeout <= 0: + timeout = None + else: + print("Warning: The timeout option requires " + "faulthandler.dump_tracebacks_later") timeout = None elif o == '--wait': input("Press any key to continue...") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 15:55:05 2011 From: python-checkins at python.org (ezio.melotti) Date: Mon, 6 Jun 2011 15:55:05 +0200 (CEST) Subject: [Python-checkins] r88853 - in tracker/instances: board/html/page.html jobs/html/page.html python-dev-spambayes-integration/html/page.html python-dev/html/page.html python-dev/rietveld/templates/base.html security/html/page.html Message-ID: <3QnyG16Bfnz7Lkd@mail.python.org> Author: ezio.melotti Date: Mon Jun 6 15:55:05 2011 New Revision: 88853 Log: Update copyright year to 2011. Modified: tracker/instances/board/html/page.html tracker/instances/jobs/html/page.html tracker/instances/python-dev-spambayes-integration/html/page.html tracker/instances/python-dev/html/page.html tracker/instances/python-dev/rietveld/templates/base.html tracker/instances/security/html/page.html Modified: tracker/instances/board/html/page.html ============================================================================== --- tracker/instances/board/html/page.html (original) +++ tracker/instances/board/html/page.html Mon Jun 6 15:55:05 2011 @@ -231,7 +231,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements Modified: tracker/instances/jobs/html/page.html ============================================================================== --- tracker/instances/jobs/html/page.html (original) +++ tracker/instances/jobs/html/page.html Mon Jun 6 15:55:05 2011 @@ -220,7 +220,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements Modified: tracker/instances/python-dev-spambayes-integration/html/page.html ============================================================================== --- tracker/instances/python-dev-spambayes-integration/html/page.html (original) +++ tracker/instances/python-dev-spambayes-integration/html/page.html Mon Jun 6 15:55:05 2011 @@ -225,7 +225,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements Modified: tracker/instances/python-dev/html/page.html ============================================================================== --- tracker/instances/python-dev/html/page.html (original) +++ tracker/instances/python-dev/html/page.html Mon Jun 6 15:55:05 2011 @@ -279,7 +279,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements Modified: tracker/instances/python-dev/rietveld/templates/base.html ============================================================================== --- tracker/instances/python-dev/rietveld/templates/base.html (original) +++ tracker/instances/python-dev/rietveld/templates/base.html Mon Jun 6 15:55:05 2011 @@ -212,7 +212,7 @@ Website maintained by the Python community
hosting by Upfront Systems
-Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements Modified: tracker/instances/security/html/page.html ============================================================================== --- tracker/instances/security/html/page.html (original) +++ tracker/instances/security/html/page.html Mon Jun 6 15:55:05 2011 @@ -231,7 +231,7 @@ hosting by Upfront Systems / powered by Roundup -Copyright © 1990-2010, Python Software Foundation
+Copyright © 1990-2011, Python Software Foundation
Legal Statements From python-checkins at python.org Mon Jun 6 17:12:52 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:12:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Remove_outdated?= =?utf8?q?_bit_of_advice_=28c882b5ff92d9_follow-up=29?= Message-ID: http://hg.python.org/cpython/rev/3eca772d57fc changeset: 70659:3eca772d57fc branch: 2.7 parent: 70635:0fd148c04e57 user: ?ric Araujo date: Sat Jun 04 18:35:04 2011 +0200 summary: Remove outdated bit of advice (c882b5ff92d9 follow-up) files: Doc/documenting/markup.rst | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:12:53 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:12:53 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Remove_unnecess?= =?utf8?q?ary_executable_bit_on_one_distutils_file?= Message-ID: http://hg.python.org/cpython/rev/d1671cdf7ed2 changeset: 70660:d1671cdf7ed2 branch: 2.7 user: ?ric Araujo date: Sat Jun 04 20:45:33 2011 +0200 summary: Remove unnecessary executable bit on one distutils file files: Lib/distutils/tests/Setup.sample | Bin 1 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:12:53 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:12:53 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/6e7a98cfcfab changeset: 70661:6e7a98cfcfab branch: 2.7 parent: 70650:6a4b67e85309 parent: 70660:d1671cdf7ed2 user: ?ric Araujo date: Mon Jun 06 17:11:31 2011 +0200 summary: Branch merge files: Doc/documenting/markup.rst | 11 ++++++----- Lib/distutils/tests/Setup.sample | Bin 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:13:47 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:13:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Point_to_new_collections=2E?= =?utf8?q?abc_module_for_collections_ABCs?= Message-ID: http://hg.python.org/cpython/rev/441ae0da70c4 changeset: 70662:441ae0da70c4 parent: 70618:41c918897286 user: ?ric Araujo date: Fri Jun 03 20:49:39 2011 +0200 summary: Point to new collections.abc module for collections ABCs files: Doc/library/abc.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -20,7 +20,7 @@ The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition the -:mod:`collections` module has some ABCs that can be used to test whether +:mod:`collections.abc` submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, is it hashable or a mapping. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:13:50 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:13:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Add_missing_section_of_doc_?= =?utf8?q?file_lost_among_repositories_and_conversions?= Message-ID: http://hg.python.org/cpython/rev/e07a5a4a1d1f changeset: 70663:e07a5a4a1d1f user: ?ric Araujo date: Sat Jun 04 02:31:14 2011 +0200 summary: Add missing section of doc file lost among repositories and conversions files: Doc/packaging/setupcfg.rst | 163 ++++++++++++++++++++++++- 1 files changed, 160 insertions(+), 3 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -4,11 +4,114 @@ Specification of the :file:`setup.cfg` file ******************************************* -.. :version: 1.0 +:version: 0.9 This document describes the :file:`setup.cfg`, an ini-style configuration file -(compatible with :class:`configparser.RawConfigParser`) configuration file used -by Packaging to replace the :file:`setup.py` file. +(compatible with :class:`configparser.RawConfigParser`) used by Packaging to +replace the :file:`setup.py` file. + + +Syntax +====== + +The configuration file is an ini-based file. Variables name can be +assigned values, and grouped into sections. A line that starts with "#" is +commented out. Empty lines are also removed. + +Example:: + + [section1] + # comment + name = value + name2 = "other value" + + [section2] + foo = bar + + +Values conversion +----------------- + +Here are a set of rules for converting values: + +- If value is quoted with " chars, it's a string. This notation is useful to + include "=" characters in the value. In case the value contains a " + character, it must be escaped with a "\" character. +- If the value is "true" or "false" --no matter what the case is--, it's + converted to a boolean, or 0 and 1 when the language does not have a + boolean type. +- A value can contains multiple lines. When read, lines are converted into a + sequence of values. Each new line for a multiple lines value must start with + a least one space or tab character. These indentation characters will be + stripped. +- all other values are considered as strings + +Examples:: + + [section] + foo = one + two + three + + bar = false + baz = 1.3 + boo = "ok" + beee = "wqdqw pojpj w\"ddq" + + +Extending files +--------------- + +An INI file can extend another file. For this, a "DEFAULT" section must contain +an "extends" variable that can point to one or several INI files which will be +merged to the current file by adding new sections and values. + +If the file pointed in "extends" contains section/variable names that already +exist in the original file, they will not override existing ones. + +file_one.ini:: + + [section1] + name2 = "other value" + + [section2] + foo = baz + bas = bar + +file_two.ini:: + + [DEFAULT] + extends = file_one.ini + + [section2] + foo = bar + +Result:: + + [section1] + name2 = "other value" + + [section2] + foo = bar + bas = bar + +To point several files, the multi-line notation can be used:: + + [DEFAULT] + extends = file_one.ini + file_two.ini + +When several files are provided, they are processed sequentially. So if the +first one has a value that is also present in the second, the second one will +be ignored. This means that the configuration goes from the most specialized to +the most common. + +**Tools will need to provide a way to produce a canonical version of the +file**. This will be useful to publish a single file. + + +Description of sections and fields +================================== Each section contains a description of its options. @@ -646,3 +749,57 @@ Option values given in the configuration file can be overriden on the command line. See :ref:`packaging-setup-config` for more information. + + +Extensibility +============= + +Every section can define new variables that are not part of the specification. +They are called **extensions**. + +An extension field starts with *X-*. + +Example:: + + [metadata] + ... + X-Debian-Name = python-distribute + + +Changes in the specification +============================ + +The version scheme for this specification is **MAJOR.MINOR**. +Changes in the specification will increment the version. + +- minor version changes (1.x): backwards compatible + + - new fields and sections (both optional and mandatory) can be added + - optional fields can be removed + +- major channges (2.X): backwards-incompatible + + - mandatory fields/sections are removed + - fields change their meaning + +As a consequence, a tool written to consume 1.X (say, X=5) has these +properties: + +- reading 1.Y, YX is also possible. The tool will just ignore the new + fields (even if they are mandatory in that version) + If optional fields were removed, the tool will just consider them absent. +- reading 2.X is not possible; the tool should refuse to interpret + the file. + +A tool written to produce 1.X should have these properties: + +- it will write all mandatory fields +- it may write optional fields + + +Acks +==== + +XXX -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:13:56 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:13:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Remove_link_tha?= =?utf8?q?t=E2=80=99s_already_present_at_the_top_of_the_file?= Message-ID: http://hg.python.org/cpython/rev/d0916184f5b1 changeset: 70664:d0916184f5b1 branch: 3.2 parent: 70617:4efc9ded0a03 user: ?ric Araujo date: Fri Jun 03 20:43:42 2011 +0200 summary: Remove link that?s already present at the top of the file files: Doc/library/collections.rst | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -1136,9 +1136,6 @@ .. seealso:: - * Latest version of the :source:`Python source code for the collections - abstract base classes ` - * `OrderedSet recipe `_ for an example built on :class:`MutableSet`. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:13:58 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:13:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Use_list_constructor_or_bui?= =?utf8?q?lt-in_method_instead_of_copy_module?= Message-ID: http://hg.python.org/cpython/rev/0975b002210f changeset: 70665:0975b002210f parent: 70663:e07a5a4a1d1f user: ?ric Araujo date: Sat Jun 04 18:45:40 2011 +0200 summary: Use list constructor or built-in method instead of copy module files: Lib/packaging/compiler/cygwinccompiler.py | 7 +++---- Lib/packaging/run.py | 3 +-- Lib/packaging/util.py | 3 +-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/packaging/compiler/cygwinccompiler.py b/Lib/packaging/compiler/cygwinccompiler.py --- a/Lib/packaging/compiler/cygwinccompiler.py +++ b/Lib/packaging/compiler/cygwinccompiler.py @@ -48,7 +48,6 @@ import os import sys -import copy from packaging import logger from packaging.compiler.unixccompiler import UnixCCompiler @@ -172,9 +171,9 @@ extra_postargs=None, build_temp=None, target_lang=None): """Link the objects.""" # use separate copies, so we can modify the lists - extra_preargs = copy.copy(extra_preargs or []) - libraries = copy.copy(libraries or []) - objects = copy.copy(objects or []) + extra_preargs = list(extra_preargs or []) + libraries = list(libraries or []) + objects = list(objects or []) # Additional libraries libraries.extend(self.dll_libraries) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -5,7 +5,6 @@ import sys import getopt import logging -from copy import copy from packaging import logger from packaging.dist import Distribution @@ -673,7 +672,7 @@ def main(args=None): old_level = logger.level - old_handlers = copy(logger.handlers) + old_handlers = list(logger.handlers) try: dispatcher = Dispatcher(args) if dispatcher.action is None: diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -14,7 +14,6 @@ import posixpath import sysconfig import subprocess -from copy import copy from glob import iglob as std_iglob from fnmatch import fnmatchcase from inspect import getsource @@ -384,7 +383,7 @@ elif optimize == 2: cmd.insert(1, "-OO") - env = copy(os.environ) + env = os.environ.copy() env['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: spawn(cmd, env=env) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:13:59 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:13:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Add_reST_target_for_Doc/pac?= =?utf8?q?kaging/setupcfg?= Message-ID: http://hg.python.org/cpython/rev/f9ff27fe9c47 changeset: 70666:f9ff27fe9c47 user: ?ric Araujo date: Sat Jun 04 18:46:25 2011 +0200 summary: Add reST target for Doc/packaging/setupcfg files: Doc/packaging/commandhooks.rst | 5 +++++ Doc/packaging/setupcfg.rst | 2 ++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst --- a/Doc/packaging/commandhooks.rst +++ b/Doc/packaging/commandhooks.rst @@ -1,3 +1,5 @@ +.. TODO integrate this in commandref and configfile + ============= Command hooks ============= @@ -9,6 +11,9 @@ processed), but before it is run. The post-hooks are run after the command itself. Both types of hooks receive an instance of the command object. +See also global setup hooks in :ref:`packaging-setupcfg`. + + Sample usage of hooks ===================== diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -1,5 +1,7 @@ .. highlightlang:: cfg +.. _packaging-setupcfg: + ******************************************* Specification of the :file:`setup.cfg` file ******************************************* -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:01 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/a37368ec4363 changeset: 70667:a37368ec4363 parent: 70632:ac562d86ab71 parent: 70666:f9ff27fe9c47 user: ?ric Araujo date: Sat Jun 04 20:37:16 2011 +0200 summary: Branch merge files: Doc/library/abc.rst | 2 +- Doc/packaging/commandhooks.rst | 5 + Doc/packaging/setupcfg.rst | 165 +++++++++- Lib/packaging/compiler/cygwinccompiler.py | 7 +- Lib/packaging/run.py | 3 +- Lib/packaging/util.py | 3 +- 6 files changed, 173 insertions(+), 12 deletions(-) diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -20,7 +20,7 @@ The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition the -:mod:`collections` module has some ABCs that can be used to test whether +:mod:`collections.abc` submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, is it hashable or a mapping. diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst --- a/Doc/packaging/commandhooks.rst +++ b/Doc/packaging/commandhooks.rst @@ -1,3 +1,5 @@ +.. TODO integrate this in commandref and configfile + ============= Command hooks ============= @@ -9,6 +11,9 @@ processed), but before it is run. The post-hooks are run after the command itself. Both types of hooks receive an instance of the command object. +See also global setup hooks in :ref:`packaging-setupcfg`. + + Sample usage of hooks ===================== diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -1,14 +1,119 @@ .. highlightlang:: cfg +.. _packaging-setupcfg: + ******************************************* Specification of the :file:`setup.cfg` file ******************************************* -.. :version: 1.0 +:version: 0.9 This document describes the :file:`setup.cfg`, an ini-style configuration file -(compatible with :class:`configparser.RawConfigParser`) configuration file used -by Packaging to replace the :file:`setup.py` file. +(compatible with :class:`configparser.RawConfigParser`) used by Packaging to +replace the :file:`setup.py` file. + + +Syntax +====== + +The configuration file is an ini-based file. Variables name can be +assigned values, and grouped into sections. A line that starts with "#" is +commented out. Empty lines are also removed. + +Example:: + + [section1] + # comment + name = value + name2 = "other value" + + [section2] + foo = bar + + +Values conversion +----------------- + +Here are a set of rules for converting values: + +- If value is quoted with " chars, it's a string. This notation is useful to + include "=" characters in the value. In case the value contains a " + character, it must be escaped with a "\" character. +- If the value is "true" or "false" --no matter what the case is--, it's + converted to a boolean, or 0 and 1 when the language does not have a + boolean type. +- A value can contains multiple lines. When read, lines are converted into a + sequence of values. Each new line for a multiple lines value must start with + a least one space or tab character. These indentation characters will be + stripped. +- all other values are considered as strings + +Examples:: + + [section] + foo = one + two + three + + bar = false + baz = 1.3 + boo = "ok" + beee = "wqdqw pojpj w\"ddq" + + +Extending files +--------------- + +An INI file can extend another file. For this, a "DEFAULT" section must contain +an "extends" variable that can point to one or several INI files which will be +merged to the current file by adding new sections and values. + +If the file pointed in "extends" contains section/variable names that already +exist in the original file, they will not override existing ones. + +file_one.ini:: + + [section1] + name2 = "other value" + + [section2] + foo = baz + bas = bar + +file_two.ini:: + + [DEFAULT] + extends = file_one.ini + + [section2] + foo = bar + +Result:: + + [section1] + name2 = "other value" + + [section2] + foo = bar + bas = bar + +To point several files, the multi-line notation can be used:: + + [DEFAULT] + extends = file_one.ini + file_two.ini + +When several files are provided, they are processed sequentially. So if the +first one has a value that is also present in the second, the second one will +be ignored. This means that the configuration goes from the most specialized to +the most common. + +**Tools will need to provide a way to produce a canonical version of the +file**. This will be useful to publish a single file. + + +Description of sections and fields +================================== Each section contains a description of its options. @@ -646,3 +751,57 @@ Option values given in the configuration file can be overriden on the command line. See :ref:`packaging-setup-config` for more information. + + +Extensibility +============= + +Every section can define new variables that are not part of the specification. +They are called **extensions**. + +An extension field starts with *X-*. + +Example:: + + [metadata] + ... + X-Debian-Name = python-distribute + + +Changes in the specification +============================ + +The version scheme for this specification is **MAJOR.MINOR**. +Changes in the specification will increment the version. + +- minor version changes (1.x): backwards compatible + + - new fields and sections (both optional and mandatory) can be added + - optional fields can be removed + +- major channges (2.X): backwards-incompatible + + - mandatory fields/sections are removed + - fields change their meaning + +As a consequence, a tool written to consume 1.X (say, X=5) has these +properties: + +- reading 1.Y, YX is also possible. The tool will just ignore the new + fields (even if they are mandatory in that version) + If optional fields were removed, the tool will just consider them absent. +- reading 2.X is not possible; the tool should refuse to interpret + the file. + +A tool written to produce 1.X should have these properties: + +- it will write all mandatory fields +- it may write optional fields + + +Acks +==== + +XXX diff --git a/Lib/packaging/compiler/cygwinccompiler.py b/Lib/packaging/compiler/cygwinccompiler.py --- a/Lib/packaging/compiler/cygwinccompiler.py +++ b/Lib/packaging/compiler/cygwinccompiler.py @@ -48,7 +48,6 @@ import os import sys -import copy from packaging import logger from packaging.compiler.unixccompiler import UnixCCompiler @@ -172,9 +171,9 @@ extra_postargs=None, build_temp=None, target_lang=None): """Link the objects.""" # use separate copies, so we can modify the lists - extra_preargs = copy.copy(extra_preargs or []) - libraries = copy.copy(libraries or []) - objects = copy.copy(objects or []) + extra_preargs = list(extra_preargs or []) + libraries = list(libraries or []) + objects = list(objects or []) # Additional libraries libraries.extend(self.dll_libraries) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -5,7 +5,6 @@ import sys import getopt import logging -from copy import copy from packaging import logger from packaging.dist import Distribution @@ -673,7 +672,7 @@ def main(args=None): old_level = logger.level - old_handlers = copy(logger.handlers) + old_handlers = list(logger.handlers) try: dispatcher = Dispatcher(args) if dispatcher.action is None: diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -14,7 +14,6 @@ import posixpath import sysconfig import subprocess -from copy import copy from glob import iglob as std_iglob from fnmatch import fnmatchcase from inspect import getsource @@ -384,7 +383,7 @@ elif optimize == 2: cmd.insert(1, "-OO") - env = copy(os.environ) + env = os.environ.copy() env['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: spawn(cmd, env=env) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:02 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Improve_glossar?= =?utf8?q?y_entry_for_ABCs=2E?= Message-ID: http://hg.python.org/cpython/rev/de83c46d3d59 changeset: 70668:de83c46d3d59 branch: 3.2 parent: 70664:d0916184f5b1 user: ?ric Araujo date: Sat Jun 04 18:42:38 2011 +0200 summary: Improve glossary entry for ABCs. - Rename reST target name for collections ABCs to avoid collisions - Add link to importlib ABCs (collections, numbers and io ABCs were already linked) - Link to glossary entry from numbers module doc (other modules already do it) files: Doc/glossary.rst | 14 ++++++++------ Doc/library/abc.rst | 2 +- Doc/library/collections.rst | 7 ++++--- Doc/library/numbers.rst | 6 +++--- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -27,12 +27,14 @@ :ref:`2to3-reference`. abstract base class - :ref:`abstract-base-classes` complement :term:`duck-typing` by + Abstract base classes complement :term:`duck-typing` by providing a way to define interfaces when other techniques like - :func:`hasattr` would be clumsy. Python comes with many built-in ABCs for + :func:`hasattr` would be clumsy or subtly wrong (for example with + :ref:`magic methods `). Python comes with many built-in ABCs for data structures (in the :mod:`collections` module), numbers (in the - :mod:`numbers` module), and streams (in the :mod:`io` module). You can - create your own ABC with the :mod:`abc` module. + :mod:`numbers` module), streams (in the :mod:`io` module), import finders + and loaders (in the :mod:`importlib.abc` module). You can create your own + ABCs with the :mod:`abc` module. argument A value passed to a function or method, assigned to a named local @@ -430,8 +432,8 @@ mapping A container object that supports arbitrary key lookups and implements the methods specified in the :class:`Mapping` or :class:`MutableMapping` - :ref:`abstract base classes `. Examples include - :class:`dict`, :class:`collections.defaultdict`, + :ref:`abstract base classes `. Examples + include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. metaclass diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -12,7 +12,7 @@ -------------- This module provides the infrastructure for defining an :term:`abstract base -class` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this +class` (ABC) in Python, as outlined in :pep:`3119`; see the PEP for why this was added to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -33,8 +33,9 @@ ===================== ==================================================================== In addition to the concrete container classes, the collections module provides -:ref:`abstract-base-classes` that can be used to test whether a class provides a -particular interface, for example, whether it is hashable or a mapping. +:ref:`abstract base classes ` that can be +used to test whether a class provides a particular interface, for example, +whether it is hashable or a mapping. :class:`Counter` objects @@ -984,7 +985,7 @@ subclass) or an arbitrary sequence which can be converted into a string using the built-in :func:`str` function. -.. _abstract-base-classes: +.. _collections-abstract-base-classes: ABCs - abstract base classes ---------------------------- diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -5,9 +5,9 @@ :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). -The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract -base classes which progressively define more operations. None of the types -defined in this module can be instantiated. +The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric +:term:`abstract base classes ` which progressively define +more operations. None of the types defined in this module can be instantiated. .. class:: Number -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:03 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Remove_unneeded?= =?utf8?q?_executable_bit_on_two_distutils_files?= Message-ID: http://hg.python.org/cpython/rev/51973a0776f9 changeset: 70669:51973a0776f9 branch: 3.2 user: ?ric Araujo date: Sat Jun 04 20:47:26 2011 +0200 summary: Remove unneeded executable bit on two distutils files files: Lib/distutils/tests/Setup.sample | Bin Lib/distutils/tests/test_extension.py | Bin 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/Lib/distutils/tests/test_extension.py b/Lib/distutils/tests/test_extension.py old mode 100755 new mode 100644 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:06 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_ABC_and_distutils_touch-ups_from_3=2E2=2E?= Message-ID: http://hg.python.org/cpython/rev/d035cfbad9f5 changeset: 70670:d035cfbad9f5 parent: 70667:a37368ec4363 parent: 70669:51973a0776f9 user: ?ric Araujo date: Sat Jun 04 21:16:42 2011 +0200 summary: Merge ABC and distutils touch-ups from 3.2. I have removed the reST target I added in 38cdca2cc253: it is not necessary, as people can link to the glossary entry or the abc module without it. Two indentation fixes from 3.2 collections.rst have been ported to 3.3 collections.abc.rst. files: Doc/glossary.rst | 16 +++++++------ Doc/library/abc.rst | 2 - Doc/library/collections.abc.rst | 8 +++--- Doc/library/numbers.rst | 6 ++-- Lib/distutils/tests/Setup.sample | Bin Lib/distutils/tests/test_extension.py | Bin 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -27,12 +27,14 @@ :ref:`2to3-reference`. abstract base class - :ref:`abstract-base-classes` complement :term:`duck-typing` by + Abstract base classes complement :term:`duck-typing` by providing a way to define interfaces when other techniques like - :func:`hasattr` would be clumsy. Python comes with many built-in ABCs for - data structures (in the :mod:`collections` module), numbers (in the - :mod:`numbers` module), and streams (in the :mod:`io` module). You can - create your own ABC with the :mod:`abc` module. + :func:`hasattr` would be clumsy or subtly wrong (for example with + :ref:`magic methods `). Python comes with many built-in ABCs for + data structures (in the :mod:`collections.abc` module), numbers (in the + :mod:`numbers` module), streams (in the :mod:`io` module), import finders + and loaders (in the :mod:`importlib.abc` module). You can create your own + ABCs with the :mod:`abc` module. argument A value passed to a function or method, assigned to a named local @@ -430,8 +432,8 @@ mapping A container object that supports arbitrary key lookups and implements the methods specified in the :class:`Mapping` or :class:`MutableMapping` - :ref:`abstract base classes `. Examples include - :class:`dict`, :class:`collections.defaultdict`, + :ref:`abstract base classes `. Examples + include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. metaclass diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -1,5 +1,3 @@ -.. _abstract-base-classes: - :mod:`abc` --- Abstract Base Classes ==================================== diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -44,7 +44,7 @@ :class:`Iterable`, ``index``, and ``count`` :class:`Container` -:class:`MutableSequence` :class:`Sequence` ``__setitem__`` Inherited :class:`Sequence` methods and +:class:`MutableSequence` :class:`Sequence` ``__setitem__``, Inherited :class:`Sequence` methods and ``__delitem__``, ``append``, ``reverse``, ``extend``, ``pop``, ``insert`` ``remove``, ``clear``, and ``__iadd__`` @@ -175,7 +175,7 @@ .. seealso:: - * `OrderedSet recipe `_ that uses - :class:`MutableSet`. + * `OrderedSet recipe `_ for an + example built on :class:`MutableSet`. - * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. + * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -5,9 +5,9 @@ :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). -The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract -base classes which progressively define more operations. None of the types -defined in this module can be instantiated. +The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric +:term:`abstract base classes ` which progressively define +more operations. None of the types defined in this module can be instantiated. .. class:: Number diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/Lib/distutils/tests/test_extension.py b/Lib/distutils/tests/test_extension.py old mode 100755 new mode 100644 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:07 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:07 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Improve_a_few_docstrings_in?= =?utf8?q?_packaging=2E?= Message-ID: http://hg.python.org/cpython/rev/b0e11220a6bf changeset: 70671:b0e11220a6bf user: ?ric Araujo date: Sat Jun 04 22:24:59 2011 +0200 summary: Improve a few docstrings in packaging. Also beautify import lists. Having them grouped by lenght makes it slightly easier to look for a module. files: Lib/packaging/create.py | 19 ++++++------------- Lib/packaging/util.py | 17 ++++++++--------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -1,15 +1,8 @@ -#!/usr/bin/env python """Interactive helper used to create a setup.cfg file. This script will generate a packaging configuration file by looking at the current directory and asking the user questions. It is intended to -be called as - - pysetup create - -or - - python3.3 -m packaging.create +be called as *pysetup create*. """ # Original code by Sean Reifschneider @@ -26,17 +19,17 @@ # Detect scripts (not sure how. #! outside of package?) import os +import re import imp import sys import glob -import re import shutil import sysconfig import tokenize +from hashlib import md5 +from textwrap import dedent +from functools import cmp_to_key from configparser import RawConfigParser -from textwrap import dedent -from hashlib import md5 -from functools import cmp_to_key # importing this with an underscore as it should be replaced by the # dict form or another structures for all purposes from packaging._trove import all_classifiers as _CLASSIFIERS_LIST @@ -230,7 +223,7 @@ self._write_cfg() def has_setup_py(self): - """Test for the existance of a setup.py file.""" + """Test for the existence of a setup.py file.""" return os.path.exists('setup.py') def define_cfg_values(self): diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1,19 +1,18 @@ -"""packaging.util -Miscellaneous utility functions. -""" +"""Miscellaneous utility functions.""" + +import os +import re +import csv +import sys import errno -import csv -import hashlib -import os -import sys -import re import shutil import string +import hashlib import tarfile import zipfile import posixpath +import subprocess import sysconfig -import subprocess from glob import iglob as std_iglob from fnmatch import fnmatchcase from inspect import getsource -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:08 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Cleanup_in_packaging=3A_don?= =?utf8?q?=E2=80=99t_unnecessarily_instantiate_exceptions?= Message-ID: http://hg.python.org/cpython/rev/9682744cac83 changeset: 70672:9682744cac83 user: ?ric Araujo date: Sat Jun 04 22:33:16 2011 +0200 summary: Cleanup in packaging: don?t unnecessarily instantiate exceptions files: Lib/packaging/pypi/dist.py | 2 +- Lib/packaging/pypi/simple.py | 2 +- Lib/packaging/run.py | 2 +- Lib/packaging/tests/test_uninstall.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -135,7 +135,7 @@ not return one existing distribution. """ if len(self.dists) == 0: - raise LookupError() + raise LookupError if dist_type: return self[dist_type] if prefer_source: diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -189,7 +189,7 @@ self._process_index_page(predicate.name) if predicate.name.lower() not in self._projects: - raise ProjectNotFound() + raise ProjectNotFound releases = self._projects.get(predicate.name.lower()) releases.sort_releases(prefer_final=prefer_final) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -383,7 +383,7 @@ """ #opts = _parse_args(args[1:], '', ['simple', 'xmlrpc']) # 1. what kind of index is requested ? (xmlrpc / simple) - raise NotImplementedError() + raise NotImplementedError actions = [ diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -111,7 +111,7 @@ old = os.rename def _rename(source, target): - raise OSError() + raise OSError os.rename = _rename try: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:08 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Make_help_messages_in_packa?= =?utf8?q?ging=2Erun_more_consistent?= Message-ID: http://hg.python.org/cpython/rev/64ba54839833 changeset: 70673:64ba54839833 user: ?ric Araujo date: Sat Jun 04 22:33:59 2011 +0200 summary: Make help messages in packaging.run more consistent files: Lib/packaging/run.py | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -34,14 +34,14 @@ Usage: pysetup create or: pysetup create --help -Create a new Python package. +Create a new Python project. """ generate_usage = """\ Usage: pysetup generate-setup or: pysetup generate-setup --help -Generates a setup.py script for backward-compatibility purposes. +Generate a setup.py script for backward-compatibility purposes. """ @@ -95,7 +95,7 @@ dist installed distribution name optional arguments: - -y auto confirm package removal + -y auto confirm distribution removal """ run_usage = """\ @@ -217,7 +217,6 @@ print('The setup.py was generated') - @action_help(graph_usage) def _graph(dispatcher, args, **kw): name = args[1] @@ -392,10 +391,10 @@ ('install', 'Install a project', _install), ('remove', 'Remove a project', _remove), ('search', 'Search for a project in the indexes', _search), - ('list', 'Search for local projects', _list), + ('list', 'List installed releases', _list), ('graph', 'Display a graph', _graph), - ('create', 'Create a Project', _create), - ('generate-setup', 'Generates a backward-comptatible setup.py', _generate) + ('create', 'Create a project', _create), + ('generate-setup', 'Generate a backward-comptatible setup.py', _generate), ] -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:09 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Clean_up_packaging=2Ecreate?= =?utf8?q?_and_add_TODO_notes_for_future_cleanups?= Message-ID: http://hg.python.org/cpython/rev/50b9fc2451f0 changeset: 70674:50b9fc2451f0 user: ?ric Araujo date: Sat Jun 04 22:36:40 2011 +0200 summary: Clean up packaging.create and add TODO notes for future cleanups files: Lib/packaging/create.py | 22 ++++++++++++++-------- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -274,9 +274,13 @@ with open(_FILENAME, 'w', encoding='utf-8') as fp: fp.write('[metadata]\n') + # TODO use metadata module instead of hard-coding field-specific + # behavior here + # simple string entries for name in ('name', 'version', 'summary', 'download_url'): fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN'))) + # optional string entries if 'keywords' in self.data and self.data['keywords']: fp.write('keywords = %s\n' % ' '.join(self.data['keywords'])) @@ -288,6 +292,7 @@ fp.write( 'description = %s\n' % '\n |'.join(self.data['description'].split('\n'))) + # multiple use string entries for name in ('platform', 'supported-platform', 'classifier', 'requires-dist', 'provides-dist', 'obsoletes-dist', @@ -322,8 +327,8 @@ def setup_mock(**attrs): """Mock the setup(**attrs) in order to retrieve metadata.""" - # use the distutils v1 processings to correctly parse metadata. - #XXX we could also use the setuptools distibution ??? + + # TODO use config and metadata instead of Distribution from distutils.dist import Distribution dist = Distribution(attrs) dist.parse_config_files() @@ -355,13 +360,14 @@ data['modules'].extend(dist.py_modules or []) # 2.1 data_files -> resources if dist.data_files: - if len(dist.data_files) < 2 or \ - isinstance(dist.data_files[1], str): + if (len(dist.data_files) < 2 or + isinstance(dist.data_files[1], str)): dist.data_files = [('', dist.data_files)] # add tokens in the destination paths vars = {'distribution.name': data['name']} path_tokens = list(sysconfig.get_paths(vars=vars).items()) + # TODO replace this with a key function def length_comparison(x, y): len_x = len(x[1]) len_y = len(y[1]) @@ -384,12 +390,12 @@ dest = ('{%s}' % tok) + dest[len(path):] files = [('/ '.join(src.rsplit('/', 1)), dest) - for src in srcs] + for src in srcs] data['resources'].extend(files) # 2.2 package_data -> extra_files package_dirs = dist.package_dir or {} - for package, extras in iter(dist.package_data.items()) or []: + for package, extras in dist.package_data.items() or []: package_dir = package_dirs.get(package, package) for file_ in extras: if package_dir: @@ -451,10 +457,10 @@ if match: self.data['name'] = match.group(1) self.data['version'] = match.group(2) - # TODO Needs tested! + # TODO needs testing! if not is_valid_version(self.data['version']): msg = "Invalid version discovered: %s" % self.data['version'] - raise RuntimeError(msg) + raise ValueError(msg) def query_user(self): self.data['name'] = ask('Project name', self.data['name'], -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:10 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Improve_consistency_in_ques?= =?utf8?q?tions_asked_by_packaging=2Ecreate=2E?= Message-ID: http://hg.python.org/cpython/rev/33f680ed54ac changeset: 70675:33f680ed54ac user: ?ric Araujo date: Sat Jun 04 22:37:57 2011 +0200 summary: Improve consistency in questions asked by packaging.create. I reworded ?wizard? because it is a Windows-specific term. files: Lib/packaging/create.py | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -61,7 +61,7 @@ 'do_classifier': ''' Trove classifiers are optional identifiers that allow you to specify the intended audience by saying things like "Beta software with a text UI -for Linux under the PSF license. However, this can be a somewhat involved +for Linux under the PSF license". However, this can be a somewhat involved process. ''', 'packages': ''' @@ -88,7 +88,7 @@ ''', 'setup.py found': ''' The setup.py script will be executed to retrieve the metadata. -A wizard will be run if you answer "n", +An interactive helper will be run if you answer "n", ''', } @@ -475,25 +475,25 @@ self.data.get('author'), _helptext['author']) self.data['author_email'] = ask('Author e-mail address', self.data.get('author_email'), _helptext['author_email']) - self.data['home_page'] = ask('Project Home Page', + self.data['home_page'] = ask('Project home page', self.data.get('home_page'), _helptext['home_page'], required=False) if ask_yn('Do you want me to automatically build the file list ' - 'with everything I can find in the current directory ? ' + 'with everything I can find in the current directory? ' 'If you say no, you will have to define them manually.') == 'y': self._find_files() else: - while ask_yn('Do you want to add a single module ?' + while ask_yn('Do you want to add a single module?' ' (you will be able to add full packages next)', helptext=_helptext['modules']) == 'y': self._set_multi('Module name', 'modules') - while ask_yn('Do you want to add a package ?', + while ask_yn('Do you want to add a package?', helptext=_helptext['packages']) == 'y': self._set_multi('Package name', 'packages') - while ask_yn('Do you want to add an extra file ?', + while ask_yn('Do you want to add an extra file?', helptext=_helptext['extra_files']) == 'y': self._set_multi('Extra file/dir name', 'extra_files') @@ -581,7 +581,7 @@ self.set_other_classifier(self.classifiers) def set_other_classifier(self, classifiers): - if ask_yn('Do you want to set other trove identifiers', 'n', + if ask_yn('Do you want to set other trove identifiers?', 'n', _helptext['trove_generic']) != 'y': return self.walk_classifiers(classifiers, [CLASSIFIERS], '') @@ -598,7 +598,7 @@ classifiers.add(desc[4:] + ' :: ' + key) continue - if ask_yn('Do you want to set items under\n "%s" (%d sub-items)' + if ask_yn('Do you want to set items under\n "%s" (%d sub-items)?' % (key, len(trove[key])), 'n', _helptext['trove_generic']) == 'y': self.walk_classifiers(classifiers, trovepath + [trove[key]], @@ -606,7 +606,7 @@ def set_license(self, classifiers): while True: - license = ask('What license do you use', + license = ask('What license do you use?', helptext=_helptext['trove_license'], required=False) if not license: return -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:10 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Update_doctring_now_that_Py?= =?utf8?q?thon_has_real_booleans?= Message-ID: http://hg.python.org/cpython/rev/391962af78d1 changeset: 70676:391962af78d1 user: ?ric Araujo date: Mon Jun 06 01:13:48 2011 +0200 summary: Update doctring now that Python has real booleans files: Lib/packaging/util.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -271,7 +271,7 @@ def strtobool(val): - """Convert a string representation of truth to true (1) or false (0). + """Convert a string representation of truth to a boolean. True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:11 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Add_a_short_table_of_conten?= =?utf8?q?ts_to_the_setup=2Ecfg_spec=2E?= Message-ID: http://hg.python.org/cpython/rev/9d4c072dbd75 changeset: 70677:9d4c072dbd75 user: ?ric Araujo date: Mon Jun 06 01:52:37 2011 +0200 summary: Add a short table of contents to the setup.cfg spec. I tried shortening the sidebar ToC with the tocdepth option instead, but it has a bug which caused all headings with a level deeper than the tocdepth value to all have the same section number, which was a usability regression rather than in improvement. files: Doc/packaging/setupcfg.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -12,6 +12,10 @@ (compatible with :class:`configparser.RawConfigParser`) used by Packaging to replace the :file:`setup.py` file. +.. contents:: + :depth: 3 + :local: + Syntax ====== -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:12 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Change_reST_targets_in_setu?= =?utf8?q?p=2Ecfg_spec=2E?= Message-ID: http://hg.python.org/cpython/rev/b10c5f550145 changeset: 70678:b10c5f550145 user: ?ric Araujo date: Mon Jun 06 01:54:54 2011 +0200 summary: Change reST targets in setup.cfg spec. I chose ?setupcfg? as prefix instead of ?packaging-setupcfg? because the scope of the spec is not limited to packaging: it?s intended as a language-agnostic document for packaging tools developers as well as Python authors. files: Doc/packaging/commandhooks.rst | 2 +- Doc/packaging/setupcfg.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst --- a/Doc/packaging/commandhooks.rst +++ b/Doc/packaging/commandhooks.rst @@ -11,7 +11,7 @@ processed), but before it is run. The post-hooks are run after the command itself. Both types of hooks receive an instance of the command object. -See also global setup hooks in :ref:`packaging-setupcfg`. +See also global setup hooks in :ref:`setupcfg-spec`. Sample usage of hooks diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -1,6 +1,6 @@ .. highlightlang:: cfg -.. _packaging-setupcfg: +.. _setupcfg-spec: ******************************************* Specification of the :file:`setup.cfg` file @@ -387,7 +387,7 @@ **destination**. In the previous example, **doc/doc.man** will be placed in **destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in **destination_scripts/scripts/foo.sh**. (If you want more control on the final -path, take a look at base_prefix_). +path, take a look at :ref:`setupcfg-resources-base-prefix`). The **destination** part of resources declaration are paths with categories. Indeed, it's generally a bad idea to give absolute path as it will be cross @@ -511,7 +511,7 @@ More control on destination part ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _base_prefix: +.. _setupcfg-resources-base-prefix: Defining a base prefix """""""""""""""""""""" -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:12 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Rephrase_and_update_intro_a?= =?utf8?q?nd_syntax_sections_of_setupcfg?= Message-ID: http://hg.python.org/cpython/rev/e09ce1308aff changeset: 70679:e09ce1308aff user: ?ric Araujo date: Mon Jun 06 02:07:24 2011 +0200 summary: Rephrase and update intro and syntax sections of setupcfg files: Doc/packaging/setupcfg.rst | 65 +++++++++++++------------ 1 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -9,8 +9,10 @@ :version: 0.9 This document describes the :file:`setup.cfg`, an ini-style configuration file -(compatible with :class:`configparser.RawConfigParser`) used by Packaging to -replace the :file:`setup.py` file. +used by Packaging to replace the :file:`setup.py` file used by Distutils. +This specification is language-agnostic, and will therefore repeat some +information that's already documented for Python in the +:class:`configparser.RawConfigParser` documentation. .. contents:: :depth: 3 @@ -20,11 +22,10 @@ Syntax ====== -The configuration file is an ini-based file. Variables name can be -assigned values, and grouped into sections. A line that starts with "#" is -commented out. Empty lines are also removed. - -Example:: +The ini-style format used in the configuration file is a simple collection of +sections that group sets of key-value fields separated by ``=`` or ``:`` and +optional whitespace. Lines starting with ``#`` or ``;`` are comments and will +be ignored. Empty lines are also ignored. Example:: [section1] # comment @@ -35,22 +36,24 @@ foo = bar -Values conversion ------------------ +Parsing values +--------------- -Here are a set of rules for converting values: +Here are a set of rules to parse values: -- If value is quoted with " chars, it's a string. This notation is useful to - include "=" characters in the value. In case the value contains a " - character, it must be escaped with a "\" character. -- If the value is "true" or "false" --no matter what the case is--, it's - converted to a boolean, or 0 and 1 when the language does not have a - boolean type. -- A value can contains multiple lines. When read, lines are converted into a - sequence of values. Each new line for a multiple lines value must start with - a least one space or tab character. These indentation characters will be - stripped. -- all other values are considered as strings +- If a value is quoted with ``"`` chars, it's a string. If a quote character is + present in the quoted value, it can be escaped as ``\"`` or left as-is. + +- If the value is ``true``, ``t``, ``yes``, ``y`` (case-insensitive) or ``1``, + it's converted to the language equivalent of a ``True`` value; if it's + ``false``, ``f``, ``no``, ``n`` (case-insensitive) or ``0``, it's converted to + the equivalent of ``False``. + +- A value can contain multiple lines. When read, lines are converted into a + sequence of values. Each line after the first must start with a least one + space or tab character; this leading indentation will be stripped. + +- All other values are considered strings. Examples:: @@ -68,12 +71,12 @@ Extending files --------------- -An INI file can extend another file. For this, a "DEFAULT" section must contain -an "extends" variable that can point to one or several INI files which will be -merged to the current file by adding new sections and values. +A configuration file can be extended (i.e. included) by other files. For this, +a ``DEFAULT`` section must contain an ``extends`` key which value points to one +or more files which will be merged into the current files by adding new sections +and fields. If a file loaded by ``extends`` contains sections or keys that +already exist in the original file, they will not override the previous values. -If the file pointed in "extends" contains section/variable names that already -exist in the original file, they will not override existing ones. file_one.ini:: @@ -107,13 +110,12 @@ extends = file_one.ini file_two.ini -When several files are provided, they are processed sequentially. So if the -first one has a value that is also present in the second, the second one will -be ignored. This means that the configuration goes from the most specialized to -the most common. +When several files are provided, they are processed sequentially, following the +precedence rules explained above. This means that the list of files should go +from most specialized to most common. -**Tools will need to provide a way to produce a canonical version of the -file**. This will be useful to publish a single file. +**Tools will need to provide a way to produce a merged version of the +file**. This will be useful to let users publish a single file. Description of sections and fields -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:13 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Make_example_of_file_inclus?= =?utf8?q?ion_in_setupcfg_more_obvious?= Message-ID: http://hg.python.org/cpython/rev/4cd8469e15ef changeset: 70680:4cd8469e15ef user: ?ric Araujo date: Mon Jun 06 01:58:25 2011 +0200 summary: Make example of file inclusion in setupcfg more obvious files: Doc/packaging/setupcfg.rst | 29 ++++++++++++------------- 1 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -77,38 +77,37 @@ and fields. If a file loaded by ``extends`` contains sections or keys that already exist in the original file, they will not override the previous values. - -file_one.ini:: +Contents of :file:`one.cfg`:: [section1] - name2 = "other value" + name = value [section2] - foo = baz - bas = bar + foo = foo from one.cfg -file_two.ini:: +Contents of :file:`two.cfg`:: [DEFAULT] - extends = file_one.ini + extends = one.cfg [section2] - foo = bar + foo = foo from two.cfg + baz = baz from two.cfg -Result:: +The result of parsing :file:`two.cfg` is equivalent to this file:: [section1] - name2 = "other value" + name = value [section2] - foo = bar - bas = bar + foo = foo from one.cfg + baz = baz from two.cfg -To point several files, the multi-line notation can be used:: +Example use of multi-line notation to include more than one file:: [DEFAULT] - extends = file_one.ini - file_two.ini + extends = one.cfg + two.cfg When several files are provided, they are processed sequentially, following the precedence rules explained above. This means that the list of files should go -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:13 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Move_a_non-PEP_345_field_at?= =?utf8?q?_the_end_of_the_metadata_fields_list?= Message-ID: http://hg.python.org/cpython/rev/b5e743bf7f55 changeset: 70681:b5e743bf7f55 user: ?ric Araujo date: Mon Jun 06 01:58:54 2011 +0200 summary: Move a non-PEP 345 field at the end of the metadata fields list files: Doc/packaging/setupcfg.rst | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -218,10 +218,6 @@ in Distutils1.) A file can be provided in the *description-file* field. *optional* -description-file - path to a text file that will be used for the - **description** field. *optional* - keywords A list of additional keywords to be used to assist searching for the distribution in a larger catalog. Comma or space-separated. @@ -282,6 +278,13 @@ A label, followed by a browsable URL for the project. "label, url". The label is limited to 32 signs. *optional*, *multi* +One extra field not present in PEP 345 is supported: + +description-file + Path to a text file that will be used to fill the ``description`` field. + ``description-file`` and ``description`` are mutually exclusive. *optional* + + Example:: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:14 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Minor_rework_of_the_extensi?= =?utf8?q?bility_and_acks_sections?= Message-ID: http://hg.python.org/cpython/rev/1aae15e2bd5f changeset: 70682:1aae15e2bd5f user: ?ric Araujo date: Mon Jun 06 02:00:03 2011 +0200 summary: Minor rework of the extensibility and acks sections files: Doc/packaging/setupcfg.rst | 26 +++++++++++++++++--------- 1 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -764,15 +764,13 @@ Extensibility ============= -Every section can define new variables that are not part of the specification. -They are called **extensions**. +Every section can have fields that are not part of this specification. They are +called **extensions**. -An extension field starts with *X-*. - -Example:: +An extension field starts with ``X-``. Example:: [metadata] - ... + name = Distribute X-Debian-Name = python-distribute @@ -809,7 +807,17 @@ - it may write optional fields -Acks -==== -XXX + + +Acknowledgments +=============== + +This specification includes work and feedback from these people: + +- Tarek Ziad? +- Julien Jehannet +- Boris Feld +- ?ric Araujo + +(If your name is missing, please :ref:`let us know `.) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:14 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_a_few_typos?= Message-ID: http://hg.python.org/cpython/rev/ac15e2567414 changeset: 70683:ac15e2567414 user: ?ric Araujo date: Mon Jun 06 02:00:54 2011 +0200 summary: Fix a few typos files: Doc/packaging/setupcfg.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -521,7 +521,7 @@ """""""""""""""""""""" When you define your resources, you can have more control of how the final path -is compute. +is computed. By default, the final path is:: @@ -548,7 +548,7 @@ .. note:: - Glob syntax is working the same way with standard source and splitted source. + Glob syntax is working the same way with standard source and split source. So these rules:: docs/* @@ -557,7 +557,7 @@ Will match all the files in the docs directory. -When you use splitted source, the final path is compute in this way:: +When you use split source, the final path is computed this way:: destination + prefix -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:15 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:15 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Rephrase_the_section_about_?= =?utf8?q?spec_versioning?= Message-ID: http://hg.python.org/cpython/rev/b6c442314634 changeset: 70684:b6c442314634 user: ?ric Araujo date: Mon Jun 06 02:02:34 2011 +0200 summary: Rephrase the section about spec versioning files: Doc/packaging/setupcfg.rst | 39 ++++++++++++------------- 1 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -777,37 +777,36 @@ Changes in the specification ============================ -The version scheme for this specification is **MAJOR.MINOR**. -Changes in the specification will increment the version. +The versioning scheme for this specification is **MAJOR.MINOR**. Changes in the +specification will cause the version number to be updated. -- minor version changes (1.x): backwards compatible +Changes to the minor number reflect backwards-compatible changes: - - new fields and sections (both optional and mandatory) can be added - - optional fields can be removed +- New fields and sections (optional or mandatory) can be added. +- Optional fields can be removed. -- major channges (2.X): backwards-incompatible +The major number will be incremented for backwards-incompatible changes: - - mandatory fields/sections are removed - - fields change their meaning +- Mandatory fields or sections are removed. +- Fields change their meaning. -As a consequence, a tool written to consume 1.X (say, X=5) has these -properties: +As a consequence, a tool written to consume 1.5 has these properties: -- reading 1.Y, YX is also possible. The tool will just ignore the new - fields (even if they are mandatory in that version) - If optional fields were removed, the tool will just consider them absent. -- reading 2.X is not possible; the tool should refuse to interpret - the file. +- Can read 1.1, 1.2 and all versions < 1.5, since the tool knows what + optional fields weren't there. -A tool written to produce 1.X should have these properties: + .. XXX clarify -- it will write all mandatory fields -- it may write optional fields +- Can also read 1.6 and other 1.x versions: The tool will just ignore fields it + doesn't know about, even if they are mandatory in the new version. If + optional fields were removed, the tool will just consider them absent. +- Cannot read 2.x and should refuse to interpret such files. +A tool written to produce 1.x should have these properties: +- Writes all mandatory fields. +- May write optional fields. Acknowledgments -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:16 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:16 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_wsgiref=2Eegg-info_f?= =?utf8?q?rom_msi=2Epy_=28follow-up_to_d615eb7bce33=2C_=2312218=29?= Message-ID: http://hg.python.org/cpython/rev/cc28bc86d474 changeset: 70685:cc28bc86d474 parent: 70658:7ffc5ececcb3 user: ?ric Araujo date: Mon Jun 06 17:08:41 2011 +0200 summary: Remove wsgiref.egg-info from msi.py (follow-up to d615eb7bce33, #12218) files: Tools/msi/msi.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1010,8 +1010,6 @@ lib.remove_pyc() # package READMEs if present lib.glob("README") - if dir=='Lib': - lib.add_file('wsgiref.egg-info') if dir=='test' and parent.physical=='Lib': lib.add_file("185test.db") lib.add_file("audiotest.au") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:16 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:16 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/1a1522f612b0 changeset: 70686:1a1522f612b0 branch: 3.2 parent: 70646:52405ec0c8d1 parent: 70669:51973a0776f9 user: ?ric Araujo date: Mon Jun 06 17:11:47 2011 +0200 summary: Branch merge files: Doc/glossary.rst | 14 ++++++++------ Doc/library/abc.rst | 2 +- Doc/library/collections.rst | 10 ++++------ Doc/library/numbers.rst | 6 +++--- Lib/distutils/tests/Setup.sample | Bin Lib/distutils/tests/test_extension.py | Bin 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -27,12 +27,14 @@ :ref:`2to3-reference`. abstract base class - :ref:`abstract-base-classes` complement :term:`duck-typing` by + Abstract base classes complement :term:`duck-typing` by providing a way to define interfaces when other techniques like - :func:`hasattr` would be clumsy. Python comes with many built-in ABCs for + :func:`hasattr` would be clumsy or subtly wrong (for example with + :ref:`magic methods `). Python comes with many built-in ABCs for data structures (in the :mod:`collections` module), numbers (in the - :mod:`numbers` module), and streams (in the :mod:`io` module). You can - create your own ABC with the :mod:`abc` module. + :mod:`numbers` module), streams (in the :mod:`io` module), import finders + and loaders (in the :mod:`importlib.abc` module). You can create your own + ABCs with the :mod:`abc` module. argument A value passed to a function or method, assigned to a named local @@ -430,8 +432,8 @@ mapping A container object that supports arbitrary key lookups and implements the methods specified in the :class:`Mapping` or :class:`MutableMapping` - :ref:`abstract base classes `. Examples include - :class:`dict`, :class:`collections.defaultdict`, + :ref:`abstract base classes `. Examples + include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. metaclass diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -12,7 +12,7 @@ -------------- This module provides the infrastructure for defining an :term:`abstract base -class` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this +class` (ABC) in Python, as outlined in :pep:`3119`; see the PEP for why this was added to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -33,8 +33,9 @@ ===================== ==================================================================== In addition to the concrete container classes, the collections module provides -:ref:`abstract-base-classes` that can be used to test whether a class provides a -particular interface, for example, whether it is hashable or a mapping. +:ref:`abstract base classes ` that can be +used to test whether a class provides a particular interface, for example, +whether it is hashable or a mapping. :class:`Counter` objects @@ -984,7 +985,7 @@ subclass) or an arbitrary sequence which can be converted into a string using the built-in :func:`str` function. -.. _abstract-base-classes: +.. _collections-abstract-base-classes: ABCs - abstract base classes ---------------------------- @@ -1136,9 +1137,6 @@ .. seealso:: - * Latest version of the :source:`Python source code for the collections - abstract base classes ` - * `OrderedSet recipe `_ for an example built on :class:`MutableSet`. diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -5,9 +5,9 @@ :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). -The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract -base classes which progressively define more operations. None of the types -defined in this module can be instantiated. +The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric +:term:`abstract base classes ` which progressively define +more operations. None of the types defined in this module can be instantiated. .. class:: Number diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/Lib/distutils/tests/test_extension.py b/Lib/distutils/tests/test_extension.py old mode 100755 new mode 100644 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:17 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/755e398355e7 changeset: 70687:755e398355e7 parent: 70685:cc28bc86d474 parent: 70684:b6c442314634 user: ?ric Araujo date: Mon Jun 06 17:12:29 2011 +0200 summary: Branch merge files: Doc/glossary.rst | 16 +- Doc/library/abc.rst | 4 +- Doc/library/collections.abc.rst | 8 +- Doc/library/numbers.rst | 6 +- Doc/packaging/commandhooks.rst | 5 + Doc/packaging/setupcfg.rst | 198 +++++++++- Lib/distutils/tests/Setup.sample | Bin Lib/distutils/tests/test_extension.py | Bin Lib/packaging/compiler/cygwinccompiler.py | 7 +- Lib/packaging/create.py | 61 +- Lib/packaging/pypi/dist.py | 2 +- Lib/packaging/pypi/simple.py | 2 +- Lib/packaging/run.py | 18 +- Lib/packaging/tests/test_uninstall.py | 2 +- Lib/packaging/util.py | 22 +- 15 files changed, 262 insertions(+), 89 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -27,12 +27,14 @@ :ref:`2to3-reference`. abstract base class - :ref:`abstract-base-classes` complement :term:`duck-typing` by + Abstract base classes complement :term:`duck-typing` by providing a way to define interfaces when other techniques like - :func:`hasattr` would be clumsy. Python comes with many built-in ABCs for - data structures (in the :mod:`collections` module), numbers (in the - :mod:`numbers` module), and streams (in the :mod:`io` module). You can - create your own ABC with the :mod:`abc` module. + :func:`hasattr` would be clumsy or subtly wrong (for example with + :ref:`magic methods `). Python comes with many built-in ABCs for + data structures (in the :mod:`collections.abc` module), numbers (in the + :mod:`numbers` module), streams (in the :mod:`io` module), import finders + and loaders (in the :mod:`importlib.abc` module). You can create your own + ABCs with the :mod:`abc` module. argument A value passed to a function or method, assigned to a named local @@ -430,8 +432,8 @@ mapping A container object that supports arbitrary key lookups and implements the methods specified in the :class:`Mapping` or :class:`MutableMapping` - :ref:`abstract base classes `. Examples include - :class:`dict`, :class:`collections.defaultdict`, + :ref:`abstract base classes `. Examples + include :class:`dict`, :class:`collections.defaultdict`, :class:`collections.OrderedDict` and :class:`collections.Counter`. metaclass diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -1,5 +1,3 @@ -.. _abstract-base-classes: - :mod:`abc` --- Abstract Base Classes ==================================== @@ -20,7 +18,7 @@ The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition the -:mod:`collections` module has some ABCs that can be used to test whether +:mod:`collections.abc` submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, is it hashable or a mapping. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -44,7 +44,7 @@ :class:`Iterable`, ``index``, and ``count`` :class:`Container` -:class:`MutableSequence` :class:`Sequence` ``__setitem__`` Inherited :class:`Sequence` methods and +:class:`MutableSequence` :class:`Sequence` ``__setitem__``, Inherited :class:`Sequence` methods and ``__delitem__``, ``append``, ``reverse``, ``extend``, ``pop``, ``insert`` ``remove``, ``clear``, and ``__iadd__`` @@ -175,7 +175,7 @@ .. seealso:: - * `OrderedSet recipe `_ that uses - :class:`MutableSet`. + * `OrderedSet recipe `_ for an + example built on :class:`MutableSet`. - * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. + * For more about ABCs, see the :mod:`abc` module and :pep:`3119`. diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -5,9 +5,9 @@ :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.). -The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract -base classes which progressively define more operations. None of the types -defined in this module can be instantiated. +The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric +:term:`abstract base classes ` which progressively define +more operations. None of the types defined in this module can be instantiated. .. class:: Number diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst --- a/Doc/packaging/commandhooks.rst +++ b/Doc/packaging/commandhooks.rst @@ -1,3 +1,5 @@ +.. TODO integrate this in commandref and configfile + ============= Command hooks ============= @@ -9,6 +11,9 @@ processed), but before it is run. The post-hooks are run after the command itself. Both types of hooks receive an instance of the command object. +See also global setup hooks in :ref:`setupcfg-spec`. + + Sample usage of hooks ===================== diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -1,14 +1,124 @@ .. highlightlang:: cfg +.. _setupcfg-spec: + ******************************************* Specification of the :file:`setup.cfg` file ******************************************* -.. :version: 1.0 +:version: 0.9 This document describes the :file:`setup.cfg`, an ini-style configuration file -(compatible with :class:`configparser.RawConfigParser`) configuration file used -by Packaging to replace the :file:`setup.py` file. +used by Packaging to replace the :file:`setup.py` file used by Distutils. +This specification is language-agnostic, and will therefore repeat some +information that's already documented for Python in the +:class:`configparser.RawConfigParser` documentation. + +.. contents:: + :depth: 3 + :local: + + +Syntax +====== + +The ini-style format used in the configuration file is a simple collection of +sections that group sets of key-value fields separated by ``=`` or ``:`` and +optional whitespace. Lines starting with ``#`` or ``;`` are comments and will +be ignored. Empty lines are also ignored. Example:: + + [section1] + # comment + name = value + name2 = "other value" + + [section2] + foo = bar + + +Parsing values +--------------- + +Here are a set of rules to parse values: + +- If a value is quoted with ``"`` chars, it's a string. If a quote character is + present in the quoted value, it can be escaped as ``\"`` or left as-is. + +- If the value is ``true``, ``t``, ``yes``, ``y`` (case-insensitive) or ``1``, + it's converted to the language equivalent of a ``True`` value; if it's + ``false``, ``f``, ``no``, ``n`` (case-insensitive) or ``0``, it's converted to + the equivalent of ``False``. + +- A value can contain multiple lines. When read, lines are converted into a + sequence of values. Each line after the first must start with a least one + space or tab character; this leading indentation will be stripped. + +- All other values are considered strings. + +Examples:: + + [section] + foo = one + two + three + + bar = false + baz = 1.3 + boo = "ok" + beee = "wqdqw pojpj w\"ddq" + + +Extending files +--------------- + +A configuration file can be extended (i.e. included) by other files. For this, +a ``DEFAULT`` section must contain an ``extends`` key which value points to one +or more files which will be merged into the current files by adding new sections +and fields. If a file loaded by ``extends`` contains sections or keys that +already exist in the original file, they will not override the previous values. + +Contents of :file:`one.cfg`:: + + [section1] + name = value + + [section2] + foo = foo from one.cfg + +Contents of :file:`two.cfg`:: + + [DEFAULT] + extends = one.cfg + + [section2] + foo = foo from two.cfg + baz = baz from two.cfg + +The result of parsing :file:`two.cfg` is equivalent to this file:: + + [section1] + name = value + + [section2] + foo = foo from one.cfg + baz = baz from two.cfg + +Example use of multi-line notation to include more than one file:: + + [DEFAULT] + extends = one.cfg + two.cfg + +When several files are provided, they are processed sequentially, following the +precedence rules explained above. This means that the list of files should go +from most specialized to most common. + +**Tools will need to provide a way to produce a merged version of the +file**. This will be useful to let users publish a single file. + + +Description of sections and fields +================================== Each section contains a description of its options. @@ -108,10 +218,6 @@ in Distutils1.) A file can be provided in the *description-file* field. *optional* -description-file - path to a text file that will be used for the - **description** field. *optional* - keywords A list of additional keywords to be used to assist searching for the distribution in a larger catalog. Comma or space-separated. @@ -172,6 +278,13 @@ A label, followed by a browsable URL for the project. "label, url". The label is limited to 32 signs. *optional*, *multi* +One extra field not present in PEP 345 is supported: + +description-file + Path to a text file that will be used to fill the ``description`` field. + ``description-file`` and ``description`` are mutually exclusive. *optional* + + Example:: @@ -278,7 +391,7 @@ **destination**. In the previous example, **doc/doc.man** will be placed in **destination_doc/doc/doc.man** and **scripts/foo.sh** will be placed in **destination_scripts/scripts/foo.sh**. (If you want more control on the final -path, take a look at base_prefix_). +path, take a look at :ref:`setupcfg-resources-base-prefix`). The **destination** part of resources declaration are paths with categories. Indeed, it's generally a bad idea to give absolute path as it will be cross @@ -402,13 +515,13 @@ More control on destination part ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _base_prefix: +.. _setupcfg-resources-base-prefix: Defining a base prefix """""""""""""""""""""" When you define your resources, you can have more control of how the final path -is compute. +is computed. By default, the final path is:: @@ -435,7 +548,7 @@ .. note:: - Glob syntax is working the same way with standard source and splitted source. + Glob syntax is working the same way with standard source and split source. So these rules:: docs/* @@ -444,7 +557,7 @@ Will match all the files in the docs directory. -When you use splitted source, the final path is compute in this way:: +When you use split source, the final path is computed this way:: destination + prefix @@ -646,3 +759,64 @@ Option values given in the configuration file can be overriden on the command line. See :ref:`packaging-setup-config` for more information. + + +Extensibility +============= + +Every section can have fields that are not part of this specification. They are +called **extensions**. + +An extension field starts with ``X-``. Example:: + + [metadata] + name = Distribute + X-Debian-Name = python-distribute + + +Changes in the specification +============================ + +The versioning scheme for this specification is **MAJOR.MINOR**. Changes in the +specification will cause the version number to be updated. + +Changes to the minor number reflect backwards-compatible changes: + +- New fields and sections (optional or mandatory) can be added. +- Optional fields can be removed. + +The major number will be incremented for backwards-incompatible changes: + +- Mandatory fields or sections are removed. +- Fields change their meaning. + +As a consequence, a tool written to consume 1.5 has these properties: + +- Can read 1.1, 1.2 and all versions < 1.5, since the tool knows what + optional fields weren't there. + + .. XXX clarify + +- Can also read 1.6 and other 1.x versions: The tool will just ignore fields it + doesn't know about, even if they are mandatory in the new version. If + optional fields were removed, the tool will just consider them absent. + +- Cannot read 2.x and should refuse to interpret such files. + +A tool written to produce 1.x should have these properties: + +- Writes all mandatory fields. +- May write optional fields. + + +Acknowledgments +=============== + +This specification includes work and feedback from these people: + +- Tarek Ziad? +- Julien Jehannet +- Boris Feld +- ?ric Araujo + +(If your name is missing, please :ref:`let us know `.) diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample old mode 100755 new mode 100644 diff --git a/Lib/distutils/tests/test_extension.py b/Lib/distutils/tests/test_extension.py old mode 100755 new mode 100644 diff --git a/Lib/packaging/compiler/cygwinccompiler.py b/Lib/packaging/compiler/cygwinccompiler.py --- a/Lib/packaging/compiler/cygwinccompiler.py +++ b/Lib/packaging/compiler/cygwinccompiler.py @@ -48,7 +48,6 @@ import os import sys -import copy from packaging import logger from packaging.compiler.unixccompiler import UnixCCompiler @@ -172,9 +171,9 @@ extra_postargs=None, build_temp=None, target_lang=None): """Link the objects.""" # use separate copies, so we can modify the lists - extra_preargs = copy.copy(extra_preargs or []) - libraries = copy.copy(libraries or []) - objects = copy.copy(objects or []) + extra_preargs = list(extra_preargs or []) + libraries = list(libraries or []) + objects = list(objects or []) # Additional libraries libraries.extend(self.dll_libraries) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -1,15 +1,8 @@ -#!/usr/bin/env python """Interactive helper used to create a setup.cfg file. This script will generate a packaging configuration file by looking at the current directory and asking the user questions. It is intended to -be called as - - pysetup create - -or - - python3.3 -m packaging.create +be called as *pysetup create*. """ # Original code by Sean Reifschneider @@ -26,17 +19,17 @@ # Detect scripts (not sure how. #! outside of package?) import os +import re import imp import sys import glob -import re import shutil import sysconfig import tokenize +from hashlib import md5 +from textwrap import dedent +from functools import cmp_to_key from configparser import RawConfigParser -from textwrap import dedent -from hashlib import md5 -from functools import cmp_to_key # importing this with an underscore as it should be replaced by the # dict form or another structures for all purposes from packaging._trove import all_classifiers as _CLASSIFIERS_LIST @@ -68,7 +61,7 @@ 'do_classifier': ''' Trove classifiers are optional identifiers that allow you to specify the intended audience by saying things like "Beta software with a text UI -for Linux under the PSF license. However, this can be a somewhat involved +for Linux under the PSF license". However, this can be a somewhat involved process. ''', 'packages': ''' @@ -95,7 +88,7 @@ ''', 'setup.py found': ''' The setup.py script will be executed to retrieve the metadata. -A wizard will be run if you answer "n", +An interactive helper will be run if you answer "n", ''', } @@ -230,7 +223,7 @@ self._write_cfg() def has_setup_py(self): - """Test for the existance of a setup.py file.""" + """Test for the existence of a setup.py file.""" return os.path.exists('setup.py') def define_cfg_values(self): @@ -281,9 +274,13 @@ with open(_FILENAME, 'w', encoding='utf-8') as fp: fp.write('[metadata]\n') + # TODO use metadata module instead of hard-coding field-specific + # behavior here + # simple string entries for name in ('name', 'version', 'summary', 'download_url'): fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN'))) + # optional string entries if 'keywords' in self.data and self.data['keywords']: fp.write('keywords = %s\n' % ' '.join(self.data['keywords'])) @@ -295,6 +292,7 @@ fp.write( 'description = %s\n' % '\n |'.join(self.data['description'].split('\n'))) + # multiple use string entries for name in ('platform', 'supported-platform', 'classifier', 'requires-dist', 'provides-dist', 'obsoletes-dist', @@ -329,8 +327,8 @@ def setup_mock(**attrs): """Mock the setup(**attrs) in order to retrieve metadata.""" - # use the distutils v1 processings to correctly parse metadata. - #XXX we could also use the setuptools distibution ??? + + # TODO use config and metadata instead of Distribution from distutils.dist import Distribution dist = Distribution(attrs) dist.parse_config_files() @@ -362,13 +360,14 @@ data['modules'].extend(dist.py_modules or []) # 2.1 data_files -> resources if dist.data_files: - if len(dist.data_files) < 2 or \ - isinstance(dist.data_files[1], str): + if (len(dist.data_files) < 2 or + isinstance(dist.data_files[1], str)): dist.data_files = [('', dist.data_files)] # add tokens in the destination paths vars = {'distribution.name': data['name']} path_tokens = list(sysconfig.get_paths(vars=vars).items()) + # TODO replace this with a key function def length_comparison(x, y): len_x = len(x[1]) len_y = len(y[1]) @@ -391,12 +390,12 @@ dest = ('{%s}' % tok) + dest[len(path):] files = [('/ '.join(src.rsplit('/', 1)), dest) - for src in srcs] + for src in srcs] data['resources'].extend(files) # 2.2 package_data -> extra_files package_dirs = dist.package_dir or {} - for package, extras in iter(dist.package_data.items()) or []: + for package, extras in dist.package_data.items() or []: package_dir = package_dirs.get(package, package) for file_ in extras: if package_dir: @@ -458,10 +457,10 @@ if match: self.data['name'] = match.group(1) self.data['version'] = match.group(2) - # TODO Needs tested! + # TODO needs testing! if not is_valid_version(self.data['version']): msg = "Invalid version discovered: %s" % self.data['version'] - raise RuntimeError(msg) + raise ValueError(msg) def query_user(self): self.data['name'] = ask('Project name', self.data['name'], @@ -476,25 +475,25 @@ self.data.get('author'), _helptext['author']) self.data['author_email'] = ask('Author e-mail address', self.data.get('author_email'), _helptext['author_email']) - self.data['home_page'] = ask('Project Home Page', + self.data['home_page'] = ask('Project home page', self.data.get('home_page'), _helptext['home_page'], required=False) if ask_yn('Do you want me to automatically build the file list ' - 'with everything I can find in the current directory ? ' + 'with everything I can find in the current directory? ' 'If you say no, you will have to define them manually.') == 'y': self._find_files() else: - while ask_yn('Do you want to add a single module ?' + while ask_yn('Do you want to add a single module?' ' (you will be able to add full packages next)', helptext=_helptext['modules']) == 'y': self._set_multi('Module name', 'modules') - while ask_yn('Do you want to add a package ?', + while ask_yn('Do you want to add a package?', helptext=_helptext['packages']) == 'y': self._set_multi('Package name', 'packages') - while ask_yn('Do you want to add an extra file ?', + while ask_yn('Do you want to add an extra file?', helptext=_helptext['extra_files']) == 'y': self._set_multi('Extra file/dir name', 'extra_files') @@ -582,7 +581,7 @@ self.set_other_classifier(self.classifiers) def set_other_classifier(self, classifiers): - if ask_yn('Do you want to set other trove identifiers', 'n', + if ask_yn('Do you want to set other trove identifiers?', 'n', _helptext['trove_generic']) != 'y': return self.walk_classifiers(classifiers, [CLASSIFIERS], '') @@ -599,7 +598,7 @@ classifiers.add(desc[4:] + ' :: ' + key) continue - if ask_yn('Do you want to set items under\n "%s" (%d sub-items)' + if ask_yn('Do you want to set items under\n "%s" (%d sub-items)?' % (key, len(trove[key])), 'n', _helptext['trove_generic']) == 'y': self.walk_classifiers(classifiers, trovepath + [trove[key]], @@ -607,7 +606,7 @@ def set_license(self, classifiers): while True: - license = ask('What license do you use', + license = ask('What license do you use?', helptext=_helptext['trove_license'], required=False) if not license: return diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -135,7 +135,7 @@ not return one existing distribution. """ if len(self.dists) == 0: - raise LookupError() + raise LookupError if dist_type: return self[dist_type] if prefer_source: diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -189,7 +189,7 @@ self._process_index_page(predicate.name) if predicate.name.lower() not in self._projects: - raise ProjectNotFound() + raise ProjectNotFound releases = self._projects.get(predicate.name.lower()) releases.sort_releases(prefer_final=prefer_final) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -5,7 +5,6 @@ import sys import getopt import logging -from copy import copy from packaging import logger from packaging.dist import Distribution @@ -35,14 +34,14 @@ Usage: pysetup create or: pysetup create --help -Create a new Python package. +Create a new Python project. """ generate_usage = """\ Usage: pysetup generate-setup or: pysetup generate-setup --help -Generates a setup.py script for backward-compatibility purposes. +Generate a setup.py script for backward-compatibility purposes. """ @@ -96,7 +95,7 @@ dist installed distribution name optional arguments: - -y auto confirm package removal + -y auto confirm distribution removal """ run_usage = """\ @@ -218,7 +217,6 @@ print('The setup.py was generated') - @action_help(graph_usage) def _graph(dispatcher, args, **kw): name = args[1] @@ -384,7 +382,7 @@ """ #opts = _parse_args(args[1:], '', ['simple', 'xmlrpc']) # 1. what kind of index is requested ? (xmlrpc / simple) - raise NotImplementedError() + raise NotImplementedError actions = [ @@ -393,10 +391,10 @@ ('install', 'Install a project', _install), ('remove', 'Remove a project', _remove), ('search', 'Search for a project in the indexes', _search), - ('list', 'Search for local projects', _list), + ('list', 'List installed releases', _list), ('graph', 'Display a graph', _graph), - ('create', 'Create a Project', _create), - ('generate-setup', 'Generates a backward-comptatible setup.py', _generate) + ('create', 'Create a project', _create), + ('generate-setup', 'Generate a backward-comptatible setup.py', _generate), ] @@ -673,7 +671,7 @@ def main(args=None): old_level = logger.level - old_handlers = copy(logger.handlers) + old_handlers = list(logger.handlers) try: dispatcher = Dispatcher(args) if dispatcher.action is None: diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -111,7 +111,7 @@ old = os.rename def _rename(source, target): - raise OSError() + raise OSError os.rename = _rename try: diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1,20 +1,18 @@ -"""packaging.util -Miscellaneous utility functions. -""" +"""Miscellaneous utility functions.""" + +import os +import re +import csv +import sys import errno -import csv -import hashlib -import os -import sys -import re import shutil import string +import hashlib import tarfile import zipfile import posixpath +import subprocess import sysconfig -import subprocess -from copy import copy from glob import iglob as std_iglob from fnmatch import fnmatchcase from inspect import getsource @@ -273,7 +271,7 @@ def strtobool(val): - """Convert a string representation of truth to true (1) or false (0). + """Convert a string representation of truth to a boolean. True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if @@ -384,7 +382,7 @@ elif optimize == 2: cmd.insert(1, "-OO") - env = copy(os.environ) + env = os.environ.copy() env['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: spawn(cmd, env=env) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 17:14:17 2011 From: python-checkins at python.org (eric.araujo) Date: Mon, 06 Jun 2011 17:14:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/d8502fee4638 changeset: 70688:d8502fee4638 parent: 70687:755e398355e7 parent: 70686:1a1522f612b0 user: ?ric Araujo date: Mon Jun 06 17:13:08 2011 +0200 summary: Merge 3.2 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 19:18:02 2011 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 06 Jun 2011 19:18:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2311893=3A_Remove_ob?= =?utf8?q?solete_internal_wrapper_class_=60SSLFakeFile=60_in_the?= Message-ID: http://hg.python.org/cpython/rev/b68390b6dbfd changeset: 70689:b68390b6dbfd user: Antoine Pitrou date: Mon Jun 06 19:17:09 2011 +0200 summary: Issue #11893: Remove obsolete internal wrapper class `SSLFakeFile` in the smtplib module. Patch by Catalin Iacob. files: Lib/smtplib.py | 26 +++----------------------- Misc/NEWS | 3 +++ 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -172,27 +172,6 @@ except ImportError: _have_ssl = False else: - class SSLFakeFile: - """A fake file like object that really wraps a SSLObject. - - It only supports what is needed in smtplib. - """ - def __init__(self, sslobj): - self.sslobj = sslobj - - def readline(self): - str = b"" - chr = None - while chr != b"\n": - chr = self.sslobj.read(1) - if not chr: - break - str += chr - return str - - def close(self): - pass - _have_ssl = True @@ -322,6 +301,7 @@ if self.debuglevel > 0: print('connect:', (host, port), file=stderr) self.sock = self._get_socket(host, port, self.timeout) + self.file = None (code, msg) = self.getreply() if self.debuglevel > 0: print("connect:", msg, file=stderr) @@ -669,7 +649,7 @@ self.sock = context.wrap_socket(self.sock) else: self.sock = ssl.wrap_socket(self.sock, keyfile, certfile) - self.file = SSLFakeFile(self.sock) + self.file = None # RFC 3207: # The client MUST discard any knowledge obtained from # the server, such as the list of SMTP service extensions, @@ -853,7 +833,6 @@ new_socket = self.context.wrap_socket(new_socket) else: new_socket = ssl.wrap_socket(new_socket, self.keyfile, self.certfile) - self.file = SSLFakeFile(new_socket) return new_socket __all__.append("SMTP_SSL") @@ -890,6 +869,7 @@ # Handle Unix-domain sockets. try: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.file = None self.sock.connect(host) except socket.error as msg: if self.debuglevel > 0: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #11893: Remove obsolete internal wrapper class ``SSLFakeFile`` in the + smtplib module. Patch by Catalin Iacob. + - Issue #12080: Fix a Decimal.power() case that took an unreasonably long time to compute. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 19:36:06 2011 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 06 Jun 2011 19:36:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312040=3A_Expose_a_?= =?utf8?q?new_attribute_=60sentinel=60_on_instances_of?= Message-ID: http://hg.python.org/cpython/rev/568a3ba088e4 changeset: 70690:568a3ba088e4 user: Antoine Pitrou date: Mon Jun 06 19:35:31 2011 +0200 summary: Issue #12040: Expose a new attribute `sentinel` on instances of :class:`multiprocessing.Process`. Also, fix Process.join() to not use polling anymore, when given a timeout. files: Doc/library/multiprocessing.rst | 14 +++++++ Lib/multiprocessing/forking.py | 34 ++++++++++------- Lib/multiprocessing/process.py | 12 ++++++ Lib/multiprocessing/util.py | 21 +++++++++++ Lib/test/test_multiprocessing.py | 37 ++++++++++++++++++++ Misc/NEWS | 4 ++ 6 files changed, 108 insertions(+), 14 deletions(-) diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -411,6 +411,20 @@ See :ref:`multiprocessing-auth-keys`. + .. attribute:: sentinel + + A numeric handle of a system object which will become "ready" when + the process ends. + + On Windows, this is an OS handle usable with the ``WaitForSingleObject`` + and ``WaitForMultipleObjects`` family of API calls. On Unix, this is + a file descriptor usable with primitives from the :mod:`select` module. + + You can use this value if you want to wait on several events at once. + Otherwise calling :meth:`join()` is simpler. + + .. versionadded:: 3.3 + .. method:: terminate() Terminate the process. On Unix this is done using the ``SIGTERM`` signal; diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py --- a/Lib/multiprocessing/forking.py +++ b/Lib/multiprocessing/forking.py @@ -101,10 +101,12 @@ if sys.platform != 'win32': import time + import select exit = os._exit duplicate = os.dup close = os.close + _select = util._eintr_retry(select.select) # # We define a Popen class similar to the one from subprocess, but @@ -118,8 +120,12 @@ sys.stderr.flush() self.returncode = None + r, w = os.pipe() + self.sentinel = r + self.pid = os.fork() if self.pid == 0: + os.close(r) if 'random' in sys.modules: import random random.seed() @@ -128,6 +134,11 @@ sys.stderr.flush() os._exit(code) + # `w` will be closed when the child exits, at which point `r` + # will become ready for reading (using e.g. select()). + os.close(w) + util.Finalize(self, os.close, (r,)) + def poll(self, flag=os.WNOHANG): if self.returncode is None: try: @@ -145,20 +156,14 @@ return self.returncode def wait(self, timeout=None): - if timeout is None: - return self.poll(0) - deadline = time.time() + timeout - delay = 0.0005 - while 1: - res = self.poll() - if res is not None: - break - remaining = deadline - time.time() - if remaining <= 0: - break - delay = min(delay * 2, remaining, 0.05) - time.sleep(delay) - return res + if self.returncode is None: + if timeout is not None: + r = _select([self.sentinel], [], [], timeout)[0] + if not r: + return None + # This shouldn't block if select() returned successfully. + return self.poll(os.WNOHANG if timeout == 0.0 else 0) + return self.returncode def terminate(self): if self.returncode is None: @@ -258,6 +263,7 @@ self.pid = pid self.returncode = None self._handle = hp + self.sentinel = int(hp) # send information to child prep_data = get_preparation_data(process_obj._name) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -132,6 +132,7 @@ else: from .forking import Popen self._popen = Popen(self) + self._sentinel = self._popen.sentinel _current_process._children.add(self) def terminate(self): @@ -218,6 +219,17 @@ pid = ident + @property + def sentinel(self): + ''' + Return a file descriptor (Unix) or handle (Windows) suitable for + waiting for process termination. + ''' + try: + return self._sentinel + except AttributeError: + raise ValueError("process not started") + def __repr__(self): if self is _current_process: status = 'started' diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -32,9 +32,11 @@ # SUCH DAMAGE. # +import functools import itertools import weakref import atexit +import select import threading # we want threading to install it's # cleanup function before multiprocessing does @@ -315,3 +317,22 @@ register_after_fork(self, lambda obj : obj.__dict__.clear()) def __reduce__(self): return type(self), () + + +# +# Automatic retry after EINTR +# + +def _eintr_retry(func, _errors=(EnvironmentError, select.error)): + @functools.wraps(func) + def wrapped(*args, **kwargs): + while True: + try: + return func(*args, **kwargs) + except _errors as e: + # select.error has no `errno` attribute + if e.args[0] == errno.EINTR: + continue + raise + return wrapped + diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -71,6 +71,23 @@ 'HAVE_BROKEN_SEM_GETVALUE', False) WIN32 = (sys.platform == "win32") +if WIN32: + from _subprocess import WaitForSingleObject, INFINITE, WAIT_OBJECT_0 + + def wait_for_handle(handle, timeout): + if timeout is None or timeout < 0.0: + timeout = INFINITE + else: + timeout = int(1000 * timeout) + return WaitForSingleObject(handle, timeout) == WAIT_OBJECT_0 +else: + from select import select + _select = util._eintr_retry(select) + + def wait_for_handle(handle, timeout): + if timeout is not None and timeout < 0.0: + timeout = None + return handle in _select([handle], [], [], timeout)[0] # # Some tests require ctypes @@ -307,6 +324,26 @@ ] self.assertEqual(result, expected) + @classmethod + def _test_sentinel(cls, event): + event.wait(10.0) + + def test_sentinel(self): + if self.TYPE == "threads": + return + event = self.Event() + p = self.Process(target=self._test_sentinel, args=(event,)) + with self.assertRaises(ValueError): + p.sentinel + p.start() + self.addCleanup(p.join) + sentinel = p.sentinel + self.assertIsInstance(sentinel, int) + self.assertFalse(wait_for_handle(sentinel, timeout=0.0)) + event.set() + p.join() + self.assertTrue(wait_for_handle(sentinel, timeout=DELTA)) + # # # diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,10 @@ Library ------- +- Issue #12040: Expose a new attribute ``sentinel`` on instances of + :class:`multiprocessing.Process`. Also, fix Process.join() to not use + polling anymore, when given a timeout. + - Issue #11893: Remove obsolete internal wrapper class ``SSLFakeFile`` in the smtplib module. Patch by Catalin Iacob. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 19:36:07 2011 From: python-checkins at python.org (antoine.pitrou) Date: Mon, 06 Jun 2011 19:36:07 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Whitespace_normalization?= Message-ID: http://hg.python.org/cpython/rev/4000114f9621 changeset: 70691:4000114f9621 user: Antoine Pitrou date: Mon Jun 06 19:36:01 2011 +0200 summary: Whitespace normalization files: Lib/multiprocessing/util.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -335,4 +335,3 @@ continue raise return wrapped - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 19:50:00 2011 From: python-checkins at python.org (charles-francois.natali) Date: Mon, 06 Jun 2011 19:50:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312196=3A_Make_os?= =?utf8?q?=2Epipe2=28=29_flags_argument_mandatory=2E?= Message-ID: http://hg.python.org/cpython/rev/ba975c7c33d3 changeset: 70692:ba975c7c33d3 user: Charles-Fran?ois Natali date: Mon Jun 06 19:49:47 2011 +0200 summary: Issue #12196: Make os.pipe2() flags argument mandatory. files: Doc/library/os.rst | 6 +++--- Lib/test/test_posix.py | 4 ++-- Modules/posixmodule.c | 19 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1019,11 +1019,11 @@ Availability: Unix, Windows. -.. function:: pipe2(flags=0) +.. function:: pipe2(flags) Create a pipe with *flags* set atomically. - *flags* is optional and can be constructed by ORing together zero or more of - these values: :data:`O_NONBLOCK`, :data:`O_CLOEXEC`. + *flags* can be constructed by ORing together one or more of these values: + :data:`O_NONBLOCK`, :data:`O_CLOEXEC`. Return a pair of file descriptors ``(r, w)`` usable for reading and writing, respectively. diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -481,8 +481,8 @@ self.assertRaises(TypeError, os.pipe2, 'DEADBEEF') self.assertRaises(TypeError, os.pipe2, 0, 0) - # try calling without flag, like os.pipe() - r, w = os.pipe2() + # try calling with flags = 0, like os.pipe() + r, w = os.pipe2(0) os.close(r) os.close(w) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6549,20 +6549,21 @@ #ifdef HAVE_PIPE2 PyDoc_STRVAR(posix_pipe2__doc__, -"pipe2(flags=0) -> (read_end, write_end)\n\n\ -Create a pipe with flags set atomically.\ -flags is optional and can be constructed by ORing together zero or more\n\ -of these values: O_NONBLOCK, O_CLOEXEC.\n\ +"pipe2(flags) -> (read_end, write_end)\n\n\ +Create a pipe with flags set atomically.\n\ +flags can be constructed by ORing together one or more of these values:\n\ +O_NONBLOCK, O_CLOEXEC.\n\ "); static PyObject * -posix_pipe2(PyObject *self, PyObject *args) -{ - int flags = 0; +posix_pipe2(PyObject *self, PyObject *arg) +{ + int flags; int fds[2]; int res; - if (!PyArg_ParseTuple(args, "|i:pipe2", &flags)) + flags = PyLong_AsLong(arg); + if (flags == -1 && PyErr_Occurred()) return NULL; res = pipe2(fds, flags); @@ -9467,7 +9468,7 @@ {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, #endif #ifdef HAVE_PIPE2 - {"pipe2", posix_pipe2, METH_VARARGS, posix_pipe2__doc__}, + {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__}, #endif #ifdef HAVE_MKFIFO {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 6 23:44:52 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 06 Jun 2011 23:44:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Use_a_sleep_for_test=5Fsubp?= =?utf8?q?rocess_timeout_test?= Message-ID: http://hg.python.org/cpython/rev/509622ce587a changeset: 70693:509622ce587a user: Victor Stinner date: Mon Jun 06 23:43:02 2011 +0200 summary: Use a sleep for test_subprocess timeout test instead of an active loop (while True: pass) to limit race conditions. files: Lib/test/test_subprocess.py | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -127,9 +127,10 @@ with self.assertRaises(subprocess.TimeoutExpired) as c: output = subprocess.check_output( [sys.executable, "-c", - "import sys; sys.stdout.write('BDFL')\n" + "import sys, time\n" + "sys.stdout.write('BDFL')\n" "sys.stdout.flush()\n" - "while True: pass"], + "time.sleep(3600)"], # Some heavily loaded buildbots (sparc Debian 3.x) require # this much time to start and print. timeout=3) -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Tue Jun 7 04:47:37 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 7 Jun 2011 12:47:37 +1000 Subject: [Python-checkins] cpython: Issue #12040: Expose a new attribute `sentinel` on instances of In-Reply-To: References: Message-ID: On Tue, Jun 7, 2011 at 3:36 AM, antoine.pitrou wrote: > + ? ?@property > + ? ?def sentinel(self): > + ? ? ? ?''' > + ? ? ? ?Return a file descriptor (Unix) or handle (Windows) suitable for > + ? ? ? ?waiting for process termination. > + ? ? ? ?''' > + ? ? ? ?try: > + ? ? ? ? ? ?return self._sentinel > + ? ? ? ?except AttributeError: > + ? ? ? ? ? ?raise ValueError("process not started") > + We should probably follow this model for threading.Thread.ident as well (i.e. throwing an exception rather than returning None if the thread hasn't been started yet). Also, for runtime state errors, we tend to use RuntimeError rather than ValueError (e.g. see the errors thrown by contextlib._GeneratorContextManager) Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From solipsis at pitrou.net Tue Jun 7 05:07:19 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 07 Jun 2011 05:07:19 +0200 Subject: [Python-checkins] Daily reference leaks (509622ce587a): sum=666 Message-ID: results for 509622ce587a on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 test_pydoc leaked [323, 0, 0] references, sum=323 test_pyexpat leaked [0, 0, -56] references, sum=-56 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogSS47bT', '-x'] From python-checkins at python.org Tue Jun 7 05:09:38 2011 From: python-checkins at python.org (brett.cannon) Date: Tue, 07 Jun 2011 05:09:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_When_building_sqlite3=2C_th?= =?utf8?q?e_directory_where_sqlite=2Eh_was_found_was?= Message-ID: http://hg.python.org/cpython/rev/b313fc77fa11 changeset: 70694:b313fc77fa11 user: Brett Cannon date: Mon Jun 06 20:09:10 2011 -0700 summary: When building sqlite3, the directory where sqlite.h was found was always appended to the include directories regardless of whether it was already in the list of directories. This could cause issue if sqlite was installed in the same location as another install of Python. Now a check is done to make sure the directory is not included twice. files: Misc/NEWS | 3 +++ setup.py | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -771,6 +771,9 @@ Build ----- +- Do not accidentally include the directory containing sqlite.h twice when + building sqlite3. + - Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, ensure "make install" creates symlinks in --prefix bin for the "-32" files in the framework bin directory like the installer does. diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1045,10 +1045,15 @@ else: sqlite_extra_link_args = () + include_dirs = ["Modules/_sqlite"] + # Only include the directory where sqlite was found if it does + # not already exist in set include directories, otherwise you + # can end up with a bad search path order. + if sqlite_incdir not in self.compiler.include_dirs: + include_dirs.append(sqlite_incdir) exts.append(Extension('_sqlite3', sqlite_srcs, define_macros=sqlite_defines, - include_dirs=["Modules/_sqlite", - sqlite_incdir], + include_dirs=include_dirs, library_dirs=sqlite_libdir, runtime_library_dirs=sqlite_libdir, extra_link_args=sqlite_extra_link_args, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 05:20:46 2011 From: python-checkins at python.org (brett.cannon) Date: Tue, 07 Jun 2011 05:20:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_some_extraneous_pare?= =?utf8?q?ntheses_and_swap_the_comparison_order_to?= Message-ID: http://hg.python.org/cpython/rev/fc282e375703 changeset: 70695:fc282e375703 user: Brett Cannon date: Mon Jun 06 20:20:36 2011 -0700 summary: Remove some extraneous parentheses and swap the comparison order to prevent accidental assignment. Silences a warning from LLVM/clang 2.9. files: Modules/arraymodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2091,7 +2091,7 @@ if (len == 0) { return PyUnicode_FromFormat("array('%c')", (int)typecode); } - if ((typecode == 'u')) + if ('u' == typecode) v = array_tounicode(a, NULL); else v = array_tolist(a, NULL); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 05:23:13 2011 From: python-checkins at python.org (brett.cannon) Date: Tue, 07 Jun 2011 05:23:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Checking_if_an_unsigned_lon?= =?utf8?q?g_is_=3C_0_is_pointless=2E?= Message-ID: http://hg.python.org/cpython/rev/9ef14857e49c changeset: 70696:9ef14857e49c user: Brett Cannon date: Mon Jun 06 20:22:56 2011 -0700 summary: Checking if an unsigned long is < 0 is pointless. Found by LLVM/clang 2.9. files: Modules/mmapmodule.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -645,9 +645,9 @@ return NULL; } else { /* bounds check the values */ - if (cnt < 0 || (cnt + dest) < cnt || (cnt + src) < cnt || - src < 0 || src > self->size || (src + cnt) > self->size || - dest < 0 || dest > self->size || (dest + cnt) > self->size) { + if ((cnt + dest) < cnt || (cnt + src) < cnt || + src > self->size || (src + cnt) > self->size || + dest > self->size || (dest + cnt) > self->size) { PyErr_SetString(PyExc_ValueError, "source, destination, or count out of range"); return NULL; -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 05:24:21 2011 From: python-checkins at python.org (brett.cannon) Date: Tue, 07 Jun 2011 05:24:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_a_redundant_assignme?= =?utf8?b?bnQu?= Message-ID: http://hg.python.org/cpython/rev/d7a67e7eb0e4 changeset: 70697:d7a67e7eb0e4 user: Brett Cannon date: Mon Jun 06 20:24:11 2011 -0700 summary: Remove a redundant assignment. Found by LLVM/clang 2.9. files: Modules/nismodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/nismodule.c b/Modules/nismodule.c --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -411,7 +411,7 @@ return NULL; if ((list = PyList_New(0)) == NULL) return NULL; - for (maps = maps; maps; maps = maps->next) { + for (; maps; maps = maps->next) { PyObject *str = PyUnicode_FromString(maps->map); if (!str || PyList_Append(list, str) < 0) { -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Tue Jun 7 10:22:56 2011 From: solipsis at pitrou.net (Antoine Pitrou) Date: Tue, 7 Jun 2011 10:22:56 +0200 Subject: [Python-checkins] cpython: Issue #12040: Expose a new attribute `sentinel` on instances of References: Message-ID: <20110607102256.1dabc92d@pitrou.net> On Tue, 7 Jun 2011 12:47:37 +1000 Nick Coghlan wrote: > > We should probably follow this model for threading.Thread.ident as > well (i.e. throwing an exception rather than returning None if the > thread hasn't been started yet). Well, Process.ident returns None as well ;) > Also, for runtime state errors, we tend to use RuntimeError rather > than ValueError (e.g. see the errors thrown by > contextlib._GeneratorContextManager) Well, it depends. For example, closed files raise a ValueError when you try to do operations on them. I tend to think of RuntimeError as something that happens without any clear responsibility from the user, although that's debatable (recursion errors can occur because of a programming bug, but also simply because a structure is nested much too deeply). Of course, current coding practice in other multiprocessing.Process methods and properties doesn't help, since it uses asserts to guard against misuse! Regards Antoine. From ncoghlan at gmail.com Tue Jun 7 12:10:10 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 7 Jun 2011 20:10:10 +1000 Subject: [Python-checkins] cpython: Issue #12040: Expose a new attribute `sentinel` on instances of In-Reply-To: <20110607102256.1dabc92d@pitrou.net> References: <20110607102256.1dabc92d@pitrou.net> Message-ID: On Tue, Jun 7, 2011 at 6:22 PM, Antoine Pitrou wrote: > On Tue, 7 Jun 2011 12:47:37 +1000 > Nick Coghlan wrote: >> >> We should probably follow this model for threading.Thread.ident as >> well (i.e. throwing an exception rather than returning None if the >> thread hasn't been started yet). > > Well, Process.ident returns None as well ;) Hmm, I guess in that case my preference for keeping the Thread and Process APIs reasonably consistent just edges out my dislike of returning None when a "you shouldn't do that" exception would be more appropriate. >> Also, for runtime state errors, we tend to use RuntimeError rather >> than ValueError (e.g. see the errors thrown by >> contextlib._GeneratorContextManager) > > Well, it depends. For example, closed files raise a ValueError when you > try to do operations on them. I tend to think of RuntimeError as > something that happens without any clear responsibility from the user, > although that's debatable (recursion errors can occur because of a > programming bug, but also simply because a structure is nested much too > deeply). Yeah, I only thought of the closed file counterexample after I had already posted. I guess I just have a slight personal preference for RuntimeError to flag state problems as they're less likely to be caught up in an overly broad try statement in user code (as catching RuntimeError seems to be less common than catching ValueError). > Of course, current coding practice in other multiprocessing.Process > methods and properties doesn't help, since it uses asserts to guard > against misuse! I have a vague recollection of an existing tracker issue complaining about that... or am I just remembering the one that addressed similar problems in threading? Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Tue Jun 7 12:19:39 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 07 Jun 2011 12:19:39 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogdGVzdC5zdXBwb3J0?= =?utf8?q?=3A_can=5Fsymlink=28=29_removes_the_temporary_symbolic_link?= Message-ID: http://hg.python.org/cpython/rev/3ac7f71696a1 changeset: 70698:3ac7f71696a1 branch: 3.2 parent: 70686:1a1522f612b0 user: Victor Stinner date: Tue Jun 07 12:17:15 2011 +0200 summary: test.support: can_symlink() removes the temporary symbolic link files: Lib/test/support.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1487,11 +1487,14 @@ global _can_symlink if _can_symlink is not None: return _can_symlink + symlink_path = TESTFN + "can_symlink" try: - os.symlink(TESTFN, TESTFN + "can_symlink") + os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError): can = False + else: + os.remove(symlink_path) _can_symlink = can return can -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 12:19:40 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 07 Jun 2011 12:19:40 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_test=2Esupport=3A_don=27t_catch_OSError_wh?= =?utf8?q?en_can=5Fsymlink=28=29_removes_the?= Message-ID: http://hg.python.org/cpython/rev/eaab068fbed4 changeset: 70699:eaab068fbed4 parent: 70697:d7a67e7eb0e4 parent: 70698:3ac7f71696a1 user: Victor Stinner date: Tue Jun 07 12:19:34 2011 +0200 summary: (Merge 3.2) test.support: don't catch OSError when can_symlink() removes the temporary symbolic link. files: Lib/test/support.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1561,9 +1561,10 @@ try: os.symlink(TESTFN, symlink_path) can = True - os.remove(symlink_path) except (OSError, NotImplementedError): can = False + else: + os.remove(symlink_path) _can_symlink = can return can -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Tue Jun 7 12:20:31 2011 From: solipsis at pitrou.net (Antoine Pitrou) Date: Tue, 7 Jun 2011 12:20:31 +0200 Subject: [Python-checkins] cpython: Issue #12040: Expose a new attribute `sentinel` on instances of References: <20110607102256.1dabc92d@pitrou.net> Message-ID: <20110607122031.6fb03e6e@pitrou.net> On Tue, 7 Jun 2011 20:10:10 +1000 Nick Coghlan wrote: > > > Of course, current coding practice in other multiprocessing.Process > > methods and properties doesn't help, since it uses asserts to guard > > against misuse! > > I have a vague recollection of an existing tracker issue complaining > about that... or am I just remembering the one that addressed similar > problems in threading? I don't know, but it certainly deserves fixing anyway :) Regards Antoine. From python-checkins at python.org Tue Jun 7 15:21:45 2011 From: python-checkins at python.org (lukasz.langa) Date: Tue, 07 Jun 2011 15:21:45 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzEyMjc0OiB1c2Ug?= =?utf8?q?proper_escaping_for_=25_in_IDLE_config=2E?= Message-ID: http://hg.python.org/cpython/rev/0aa3064d1cef changeset: 70700:0aa3064d1cef branch: 3.2 parent: 70698:3ac7f71696a1 user: ?ukasz Langa date: Tue Jun 07 15:19:44 2011 +0200 summary: #12274: use proper escaping for % in IDLE config. files: Lib/idlelib/config-main.def | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -46,8 +46,8 @@ [General] editor-on-startup= 0 autosave= 0 -print-command-posix=lpr %s -print-command-win=start /min notepad /p %s +print-command-posix=lpr %%s +print-command-win=start /min notepad /p %%s delete-exitfunc= 1 [EditorWindow] -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 15:21:46 2011 From: python-checkins at python.org (lukasz.langa) Date: Tue, 07 Jun 2011 15:21:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=2312274=3A_use_proper_escaping_for_=25_in_IDLE_config_=28me?= =?utf8?b?cmdlZCBmcm9tIDMuMiku?= Message-ID: http://hg.python.org/cpython/rev/b410d013e7a8 changeset: 70701:b410d013e7a8 parent: 70699:eaab068fbed4 parent: 70700:0aa3064d1cef user: ?ukasz Langa date: Tue Jun 07 15:20:51 2011 +0200 summary: #12274: use proper escaping for % in IDLE config (merged from 3.2). files: Lib/idlelib/config-main.def | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -46,8 +46,8 @@ [General] editor-on-startup= 0 autosave= 0 -print-command-posix=lpr %s -print-command-win=start /min notepad /p %s +print-command-posix=lpr %%s +print-command-win=start /min notepad /p %%s delete-exitfunc= 1 [EditorWindow] -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:00 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_documentation_of_requir?= =?utf8?q?es-python_field_in_setup=2Ecfg_=28=2311041=29?= Message-ID: http://hg.python.org/cpython/rev/d8d1bd2c4847 changeset: 70702:d8d1bd2c4847 parent: 70688:d8502fee4638 user: ?ric Araujo date: Mon Jun 06 19:57:02 2011 +0200 summary: Fix documentation of requires-python field in setup.cfg (#11041) files: Doc/packaging/setupcfg.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -265,9 +265,9 @@ Same format than *requires-dist*. *optional*, *multi*, *environ* requires-python - Specifies the Python version the distribution requires. - The value is a version number, as described in PEP 345. - *optional*, *multi*, *environ* + Specifies the Python version the distribution requires. The value is a + comma-separated list of version predicates, as described in PEP 345. + *optional*, *environ* requires-externals a dependency in the system. This field is free-form, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:01 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Update_comments_in_sysconfi?= =?utf8?q?g=2Ecfg?= Message-ID: http://hg.python.org/cpython/rev/b2fb780837b7 changeset: 70703:b2fb780837b7 user: ?ric Araujo date: Mon Jun 06 20:07:04 2011 +0200 summary: Update comments in sysconfig.cfg files: Lib/sysconfig.cfg | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/sysconfig.cfg b/Lib/sysconfig.cfg --- a/Lib/sysconfig.cfg +++ b/Lib/sysconfig.cfg @@ -1,24 +1,24 @@ [globals] -# These are the useful categories that are sometimes referenced at runtime, -# using packaging.resources.get_file: +# These are useful categories that can be referenced at run time, +# using packaging.database.get_file. # Configuration files config = {confdir}/{distribution.name} # Non-writable data that is independent of architecture (images, many xml/text files) appdata = {datadir}/{distribution.name} # Non-writable data that is architecture-dependent (some binary data formats) appdata.arch = {libdir}/{distribution.name} -# Data, written by the package, that must be preserved (databases) +# Data, written by the app/lib, that must be preserved (databases) appdata.persistent = {statedir}/lib/{distribution.name} -# Data, written by the package, that can be safely discarded (cache) +# Data, written by the app/lib, that can be safely discarded (cache) appdata.disposable = {statedir}/cache/{distribution.name} -# Help or documentation files referenced at runtime +# Help or documentation files help = {datadir}/{distribution.name} icon = {datadir}/pixmaps scripts = {base}/bin # Non-runtime files. These are valid categories for marking files for -# install, but they should not be referenced by the app at runtime: -# Help or documentation files not referenced by the package at runtime +# install, but they should not be referenced by the app/lib at run time. +# Help or documentation files doc = {datadir}/doc/{distribution.name} # GNU info documentation files info = {datadir}/info -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:02 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_comment?= Message-ID: http://hg.python.org/cpython/rev/e6f09a6367aa changeset: 70704:e6f09a6367aa user: ?ric Araujo date: Mon Jun 06 20:28:13 2011 +0200 summary: Fix comment files: Lib/packaging/tests/test_command_sdist.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -211,7 +211,7 @@ with zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) as zip_file: content = zip_file.namelist() - # Making sure everything was added. This includes 9 code and data + # Making sure everything was added. This includes 8 code and data # files in addition to PKG-INFO. self.assertEqual(len(content), 9) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:03 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Use_strings_instead_of_sets?= =?utf8?q?_of_lines_in_packaging=2Ecreate_tests=2E?= Message-ID: http://hg.python.org/cpython/rev/5853356e2359 changeset: 70705:5853356e2359 user: ?ric Araujo date: Mon Jun 06 20:59:56 2011 +0200 summary: Use strings instead of sets of lines in packaging.create tests. Using sets in tests did not check whether the values were written in the right section or with the right key. files: Lib/packaging/tests/test_create.py | 116 ++++++++-------- 1 files changed, 61 insertions(+), 55 deletions(-) diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py --- a/Lib/packaging/tests/test_create.py +++ b/Lib/packaging/tests/test_create.py @@ -13,6 +13,7 @@ support.EnvironRestorer, unittest.TestCase): + maxDiff = None restore_environ = ['PLAT'] def setUp(self): @@ -130,43 +131,45 @@ main() with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: - lines = set(line.rstrip() for line in fp) + contents = fp.read() - # FIXME don't use sets - self.assertEqual(lines, set(['', - '[metadata]', - 'version = 0.2', - 'name = pyxfoil', - 'maintainer = Andr? Espaze', - 'description = My super Death-scription', - ' |barbar is now on the public domain,', - ' |ho, baby !', - 'maintainer_email = andre.espaze at logilab.fr', - 'home_page = http://www.python-science.org/project/pyxfoil', - 'download_url = UNKNOWN', - 'summary = Python bindings for the Xfoil engine', - '[files]', - 'modules = my_lib', - ' mymodule', - 'packages = pyxfoil', - ' babar', - ' me', - 'extra_files = Martinique/Lamentin/dady', - ' Martinique/Lamentin/mumy', - ' Martinique/Lamentin/sys', - ' Martinique/Lamentin/bro', - ' Pom', - ' Flora', - ' Alexander', - ' setup.py', - ' README', - ' pyxfoil/fengine.so', - 'scripts = my_script', - ' bin/run', - 'resources =', - ' README.rst = {doc}', - ' pyxfoil.1 = {man}', - ])) + self.assertEqual(contents, dedent("""\ + [metadata] + name = pyxfoil + version = 0.2 + summary = Python bindings for the Xfoil engine + download_url = UNKNOWN + home_page = http://www.python-science.org/project/pyxfoil + maintainer = Andr? Espaze + maintainer_email = andre.espaze at logilab.fr + description = My super Death-scription + |barbar is now on the public domain, + |ho, baby ! + + [files] + packages = pyxfoil + babar + me + modules = my_lib + mymodule + scripts = my_script + bin/run + extra_files = Martinique/Lamentin/dady + Martinique/Lamentin/mumy + Martinique/Lamentin/sys + Martinique/Lamentin/bro + setup.py + README + Pom + Flora + Alexander + pyxfoil/fengine.so + + resources = + README.rst = {doc} + pyxfoil.1 = {man} + + """)) def test_convert_setup_py_to_cfg_with_description_in_readme(self): self.write_file((self.wdir, 'setup.py'), @@ -203,26 +206,29 @@ # FIXME Out of memory error. main() with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: - lines = set(line.rstrip() for line in fp) + contents = fp.read() - self.assertEqual(lines, set(['', - '[metadata]', - 'version = 0.2', - 'name = pyxfoil', - 'maintainer = Andr? Espaze', - 'maintainer_email = andre.espaze at logilab.fr', - 'home_page = http://www.python-science.org/project/pyxfoil', - 'download_url = UNKNOWN', - 'summary = Python bindings for the Xfoil engine', - 'description-file = README.txt', - '[files]', - 'packages = pyxfoil', - 'extra_files = pyxfoil/fengine.so', - ' pyxfoil/babar.so', - 'resources =', - ' README.rst = {doc}', - ' pyxfoil.1 = {man}', - ])) + self.assertEqual(contents, dedent("""\ + [metadata] + name = pyxfoil + version = 0.2 + summary = Python bindings for the Xfoil engine + download_url = UNKNOWN + home_page = http://www.python-science.org/project/pyxfoil + maintainer = Andr? Espaze + maintainer_email = andre.espaze at logilab.fr + description-file = README.txt + + [files] + packages = pyxfoil + extra_files = pyxfoil/fengine.so + pyxfoil/babar.so + + resources = + README.rst = {doc} + pyxfoil.1 = {man} + + """)) def test_suite(): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:03 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_sdist_to_always_include?= =?utf8?q?_setup=2Ecfg_=28=2311092=29=2C_to_comply_with_the_spec?= Message-ID: http://hg.python.org/cpython/rev/5940d2d82dee changeset: 70706:5940d2d82dee user: ?ric Araujo date: Mon Jun 06 21:55:43 2011 +0200 summary: Fix sdist to always include setup.cfg (#11092), to comply with the spec files: Lib/packaging/command/sdist.py | 21 ++++++---- Lib/packaging/tests/test_command_sdist.py | 13 ++++-- Lib/packaging/tests/test_create.py | 17 +++++--- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Lib/packaging/command/sdist.py b/Lib/packaging/command/sdist.py --- a/Lib/packaging/command/sdist.py +++ b/Lib/packaging/command/sdist.py @@ -201,15 +201,20 @@ self.filelist.write(self.manifest) def add_defaults(self): - """Add all the default files to self.filelist: - - all pure Python modules mentioned in setup script - - all files pointed by package_data (build_py) - - all files defined in data_files. - - all files defined as scripts. - - all C sources listed as part of extensions or C libraries - in the setup script (doesn't catch C headers!) - Everything is optional. + """Add all default files to self.filelist. + + In addition to the setup.cfg file, this will include all files returned + by the get_source_files of every registered command. This will find + Python modules and packages, data files listed in package_data_, + data_files and extra_files, scripts, C sources of extension modules or + C libraries (headers are missing). """ + if os.path.exists('setup.cfg'): + self.filelist.append('setup.cfg') + else: + logger.warning("%s: standard 'setup.cfg' file not found", + self.get_command_name()) + for cmd_name in get_command_names(): try: cmd_obj = self.get_finalized_command(cmd_name) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -34,6 +34,7 @@ MANIFEST = """\ # file GENERATED by packaging, do NOT edit inroot.txt +setup.cfg data%(sep)sdata.dt scripts%(sep)sscript.py some%(sep)sfile.txt @@ -173,6 +174,7 @@ # in package_data dist.package_data = {'': ['*.cfg', '*.dat'], 'somecode': ['*.txt']} + self.write_file((self.tmp_dir, 'setup.cfg'), '#') self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#') @@ -212,8 +214,8 @@ content = zip_file.namelist() # Making sure everything was added. This includes 8 code and data - # files in addition to PKG-INFO. - self.assertEqual(len(content), 9) + # files in addition to PKG-INFO and setup.cfg + self.assertEqual(len(content), 10) # Checking the MANIFEST with open(join(self.tmp_dir, 'MANIFEST')) as fp: @@ -230,7 +232,7 @@ cmd.ensure_finalized() cmd.run() warnings = self.get_logs(logging.WARN) - self.assertEqual(len(warnings), 3) + self.assertEqual(len(warnings), 4) # trying with a complete set of metadata self.loghandler.flush() @@ -242,8 +244,9 @@ # removing manifest generated warnings warnings = [warn for warn in warnings if not warn.endswith('-- skipping')] - # the remaining warning is about the use of the default file list - self.assertEqual(len(warnings), 1) + # the remaining warnings are about the use of the default file list and + # the absence of setup.cfg + self.assertEqual(len(warnings), 2) def test_show_formats(self): __, stdout = captured_stdout(show_formats) diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py --- a/Lib/packaging/tests/test_create.py +++ b/Lib/packaging/tests/test_create.py @@ -66,10 +66,15 @@ # building the structure tempdir = self.wdir dirs = ['pkg1', 'data', 'pkg2', 'pkg2/sub'] - files = ['README', 'setup.cfg', 'foo.py', - 'pkg1/__init__.py', 'pkg1/bar.py', - 'data/data1', 'pkg2/__init__.py', - 'pkg2/sub/__init__.py'] + files = [ + 'README', + 'data/data1', + 'foo.py', + 'pkg1/__init__.py', + 'pkg1/bar.py', + 'pkg2/__init__.py', + 'pkg2/sub/__init__.py', + ] for dir_ in dirs: os.mkdir(os.path.join(tempdir, dir_)) @@ -86,8 +91,8 @@ ['pkg1', 'pkg2', 'pkg2.sub']) self.assertEqual(mainprogram.data['modules'], ['foo']) data_fn = os.path.join('data', 'data1') - self.assertEqual(set(mainprogram.data['extra_files']), - set(['setup.cfg', 'README', data_fn])) + self.assertEqual(mainprogram.data['extra_files'], + ['README', data_fn]) def test_convert_setup_py_to_cfg(self): self.write_file((self.wdir, 'setup.py'), -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:04 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_UnboundLocalError_in_a_?= =?utf8?q?finally_block_of_one_packaging_test?= Message-ID: http://hg.python.org/cpython/rev/e0534a0846ca changeset: 70707:e0534a0846ca user: ?ric Araujo date: Mon Jun 06 22:24:19 2011 +0200 summary: Fix UnboundLocalError in a finally block of one packaging test files: Lib/packaging/tests/test_command_upload.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_command_upload.py b/Lib/packaging/tests/test_command_upload.py --- a/Lib/packaging/tests/test_command_upload.py +++ b/Lib/packaging/tests/test_command_upload.py @@ -140,8 +140,8 @@ cmd.upload_docs = True cmd.ensure_finalized() cmd.repository = self.pypi.full_address + prev_dir = os.getcwd() try: - prev_dir = os.getcwd() os.chdir(self.tmp_dir) cmd.run() finally: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 17:32:05 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 17:32:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge=3A_packaging_fixes?= Message-ID: http://hg.python.org/cpython/rev/324dd279f3f2 changeset: 70708:324dd279f3f2 parent: 70701:b410d013e7a8 parent: 70707:e0534a0846ca user: ?ric Araujo date: Tue Jun 07 17:31:39 2011 +0200 summary: Branch merge: packaging fixes files: Doc/packaging/setupcfg.rst | 6 +- Lib/packaging/command/sdist.py | 21 +- Lib/packaging/tests/test_command_sdist.py | 15 +- Lib/packaging/tests/test_command_upload.py | 2 +- Lib/packaging/tests/test_create.py | 133 +++++---- Lib/sysconfig.cfg | 14 +- 6 files changed, 105 insertions(+), 86 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -265,9 +265,9 @@ Same format than *requires-dist*. *optional*, *multi*, *environ* requires-python - Specifies the Python version the distribution requires. - The value is a version number, as described in PEP 345. - *optional*, *multi*, *environ* + Specifies the Python version the distribution requires. The value is a + comma-separated list of version predicates, as described in PEP 345. + *optional*, *environ* requires-externals a dependency in the system. This field is free-form, diff --git a/Lib/packaging/command/sdist.py b/Lib/packaging/command/sdist.py --- a/Lib/packaging/command/sdist.py +++ b/Lib/packaging/command/sdist.py @@ -201,15 +201,20 @@ self.filelist.write(self.manifest) def add_defaults(self): - """Add all the default files to self.filelist: - - all pure Python modules mentioned in setup script - - all files pointed by package_data (build_py) - - all files defined in data_files. - - all files defined as scripts. - - all C sources listed as part of extensions or C libraries - in the setup script (doesn't catch C headers!) - Everything is optional. + """Add all default files to self.filelist. + + In addition to the setup.cfg file, this will include all files returned + by the get_source_files of every registered command. This will find + Python modules and packages, data files listed in package_data_, + data_files and extra_files, scripts, C sources of extension modules or + C libraries (headers are missing). """ + if os.path.exists('setup.cfg'): + self.filelist.append('setup.cfg') + else: + logger.warning("%s: standard 'setup.cfg' file not found", + self.get_command_name()) + for cmd_name in get_command_names(): try: cmd_obj = self.get_finalized_command(cmd_name) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -34,6 +34,7 @@ MANIFEST = """\ # file GENERATED by packaging, do NOT edit inroot.txt +setup.cfg data%(sep)sdata.dt scripts%(sep)sscript.py some%(sep)sfile.txt @@ -173,6 +174,7 @@ # in package_data dist.package_data = {'': ['*.cfg', '*.dat'], 'somecode': ['*.txt']} + self.write_file((self.tmp_dir, 'setup.cfg'), '#') self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#') @@ -211,9 +213,9 @@ with zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) as zip_file: content = zip_file.namelist() - # Making sure everything was added. This includes 9 code and data - # files in addition to PKG-INFO. - self.assertEqual(len(content), 9) + # Making sure everything was added. This includes 8 code and data + # files in addition to PKG-INFO and setup.cfg + self.assertEqual(len(content), 10) # Checking the MANIFEST with open(join(self.tmp_dir, 'MANIFEST')) as fp: @@ -230,7 +232,7 @@ cmd.ensure_finalized() cmd.run() warnings = self.get_logs(logging.WARN) - self.assertEqual(len(warnings), 3) + self.assertEqual(len(warnings), 4) # trying with a complete set of metadata self.loghandler.flush() @@ -242,8 +244,9 @@ # removing manifest generated warnings warnings = [warn for warn in warnings if not warn.endswith('-- skipping')] - # the remaining warning is about the use of the default file list - self.assertEqual(len(warnings), 1) + # the remaining warnings are about the use of the default file list and + # the absence of setup.cfg + self.assertEqual(len(warnings), 2) def test_show_formats(self): __, stdout = captured_stdout(show_formats) diff --git a/Lib/packaging/tests/test_command_upload.py b/Lib/packaging/tests/test_command_upload.py --- a/Lib/packaging/tests/test_command_upload.py +++ b/Lib/packaging/tests/test_command_upload.py @@ -140,8 +140,8 @@ cmd.upload_docs = True cmd.ensure_finalized() cmd.repository = self.pypi.full_address + prev_dir = os.getcwd() try: - prev_dir = os.getcwd() os.chdir(self.tmp_dir) cmd.run() finally: diff --git a/Lib/packaging/tests/test_create.py b/Lib/packaging/tests/test_create.py --- a/Lib/packaging/tests/test_create.py +++ b/Lib/packaging/tests/test_create.py @@ -13,6 +13,7 @@ support.EnvironRestorer, unittest.TestCase): + maxDiff = None restore_environ = ['PLAT'] def setUp(self): @@ -65,10 +66,15 @@ # building the structure tempdir = self.wdir dirs = ['pkg1', 'data', 'pkg2', 'pkg2/sub'] - files = ['README', 'setup.cfg', 'foo.py', - 'pkg1/__init__.py', 'pkg1/bar.py', - 'data/data1', 'pkg2/__init__.py', - 'pkg2/sub/__init__.py'] + files = [ + 'README', + 'data/data1', + 'foo.py', + 'pkg1/__init__.py', + 'pkg1/bar.py', + 'pkg2/__init__.py', + 'pkg2/sub/__init__.py', + ] for dir_ in dirs: os.mkdir(os.path.join(tempdir, dir_)) @@ -85,8 +91,8 @@ ['pkg1', 'pkg2', 'pkg2.sub']) self.assertEqual(mainprogram.data['modules'], ['foo']) data_fn = os.path.join('data', 'data1') - self.assertEqual(set(mainprogram.data['extra_files']), - set(['setup.cfg', 'README', data_fn])) + self.assertEqual(mainprogram.data['extra_files'], + ['README', data_fn]) def test_convert_setup_py_to_cfg(self): self.write_file((self.wdir, 'setup.py'), @@ -130,43 +136,45 @@ main() with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: - lines = set(line.rstrip() for line in fp) + contents = fp.read() - # FIXME don't use sets - self.assertEqual(lines, set(['', - '[metadata]', - 'version = 0.2', - 'name = pyxfoil', - 'maintainer = Andr? Espaze', - 'description = My super Death-scription', - ' |barbar is now on the public domain,', - ' |ho, baby !', - 'maintainer_email = andre.espaze at logilab.fr', - 'home_page = http://www.python-science.org/project/pyxfoil', - 'download_url = UNKNOWN', - 'summary = Python bindings for the Xfoil engine', - '[files]', - 'modules = my_lib', - ' mymodule', - 'packages = pyxfoil', - ' babar', - ' me', - 'extra_files = Martinique/Lamentin/dady', - ' Martinique/Lamentin/mumy', - ' Martinique/Lamentin/sys', - ' Martinique/Lamentin/bro', - ' Pom', - ' Flora', - ' Alexander', - ' setup.py', - ' README', - ' pyxfoil/fengine.so', - 'scripts = my_script', - ' bin/run', - 'resources =', - ' README.rst = {doc}', - ' pyxfoil.1 = {man}', - ])) + self.assertEqual(contents, dedent("""\ + [metadata] + name = pyxfoil + version = 0.2 + summary = Python bindings for the Xfoil engine + download_url = UNKNOWN + home_page = http://www.python-science.org/project/pyxfoil + maintainer = Andr? Espaze + maintainer_email = andre.espaze at logilab.fr + description = My super Death-scription + |barbar is now on the public domain, + |ho, baby ! + + [files] + packages = pyxfoil + babar + me + modules = my_lib + mymodule + scripts = my_script + bin/run + extra_files = Martinique/Lamentin/dady + Martinique/Lamentin/mumy + Martinique/Lamentin/sys + Martinique/Lamentin/bro + setup.py + README + Pom + Flora + Alexander + pyxfoil/fengine.so + + resources = + README.rst = {doc} + pyxfoil.1 = {man} + + """)) def test_convert_setup_py_to_cfg_with_description_in_readme(self): self.write_file((self.wdir, 'setup.py'), @@ -203,26 +211,29 @@ # FIXME Out of memory error. main() with open(os.path.join(self.wdir, 'setup.cfg'), encoding='utf-8') as fp: - lines = set(line.rstrip() for line in fp) + contents = fp.read() - self.assertEqual(lines, set(['', - '[metadata]', - 'version = 0.2', - 'name = pyxfoil', - 'maintainer = Andr? Espaze', - 'maintainer_email = andre.espaze at logilab.fr', - 'home_page = http://www.python-science.org/project/pyxfoil', - 'download_url = UNKNOWN', - 'summary = Python bindings for the Xfoil engine', - 'description-file = README.txt', - '[files]', - 'packages = pyxfoil', - 'extra_files = pyxfoil/fengine.so', - ' pyxfoil/babar.so', - 'resources =', - ' README.rst = {doc}', - ' pyxfoil.1 = {man}', - ])) + self.assertEqual(contents, dedent("""\ + [metadata] + name = pyxfoil + version = 0.2 + summary = Python bindings for the Xfoil engine + download_url = UNKNOWN + home_page = http://www.python-science.org/project/pyxfoil + maintainer = Andr? Espaze + maintainer_email = andre.espaze at logilab.fr + description-file = README.txt + + [files] + packages = pyxfoil + extra_files = pyxfoil/fengine.so + pyxfoil/babar.so + + resources = + README.rst = {doc} + pyxfoil.1 = {man} + + """)) def test_suite(): diff --git a/Lib/sysconfig.cfg b/Lib/sysconfig.cfg --- a/Lib/sysconfig.cfg +++ b/Lib/sysconfig.cfg @@ -1,24 +1,24 @@ [globals] -# These are the useful categories that are sometimes referenced at runtime, -# using packaging.resources.get_file: +# These are useful categories that can be referenced at run time, +# using packaging.database.get_file. # Configuration files config = {confdir}/{distribution.name} # Non-writable data that is independent of architecture (images, many xml/text files) appdata = {datadir}/{distribution.name} # Non-writable data that is architecture-dependent (some binary data formats) appdata.arch = {libdir}/{distribution.name} -# Data, written by the package, that must be preserved (databases) +# Data, written by the app/lib, that must be preserved (databases) appdata.persistent = {statedir}/lib/{distribution.name} -# Data, written by the package, that can be safely discarded (cache) +# Data, written by the app/lib, that can be safely discarded (cache) appdata.disposable = {statedir}/cache/{distribution.name} -# Help or documentation files referenced at runtime +# Help or documentation files help = {datadir}/{distribution.name} icon = {datadir}/pixmaps scripts = {base}/bin # Non-runtime files. These are valid categories for marking files for -# install, but they should not be referenced by the app at runtime: -# Help or documentation files not referenced by the package at runtime +# install, but they should not be referenced by the app/lib at run time. +# Help or documentation files doc = {datadir}/doc/{distribution.name} # GNU info documentation files info = {datadir}/info -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 18:04:19 2011 From: python-checkins at python.org (eric.araujo) Date: Tue, 07 Jun 2011 18:04:19 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Kill_dead_code_in_importlib?= =?utf8?b?LnRlc3QuX19tYWluX18gKCMxMjAxOSwgcmV2aWV3ZWQgYnkgQnJldHQgQ2Fubm9u?= =?utf8?q?=29?= Message-ID: http://hg.python.org/cpython/rev/5392be94ea65 changeset: 70709:5392be94ea65 user: ?ric Araujo date: Tue Jun 07 17:58:50 2011 +0200 summary: Kill dead code in importlib.test.__main__ (#12019, reviewed by Brett Cannon) files: Lib/importlib/test/__main__.py | 7 +------ 1 files changed, 1 insertions(+), 6 deletions(-) diff --git a/Lib/importlib/test/__main__.py b/Lib/importlib/test/__main__.py --- a/Lib/importlib/test/__main__.py +++ b/Lib/importlib/test/__main__.py @@ -4,7 +4,6 @@ builtins.__import__ instead of importlib.__import__. """ -import importlib from importlib.test.import_ import util import os.path from test.support import run_unittest @@ -13,11 +12,7 @@ def test_main(): - if '__pycache__' in __file__: - parts = __file__.split(os.path.sep) - start_dir = sep.join(parts[:-2]) - else: - start_dir = os.path.dirname(__file__) + start_dir = os.path.dirname(__file__) top_dir = os.path.dirname(os.path.dirname(start_dir)) test_loader = unittest.TestLoader() if '--builtin' in sys.argv: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 7 23:17:44 2011 From: python-checkins at python.org (barry.warsaw) Date: Tue, 07 Jun 2011 23:17:44 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_A_few_small_clarifications=2E?= Message-ID: http://hg.python.org/peps/rev/ce04352dda1d changeset: 3884:ce04352dda1d user: Barry Warsaw date: Tue Jun 07 17:17:29 2011 -0400 summary: A few small clarifications. files: pep-0396.txt | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pep-0396.txt b/pep-0396.txt --- a/pep-0396.txt +++ b/pep-0396.txt @@ -105,7 +105,7 @@ #. When a module includes a version number, it SHOULD be available in the ``__version__`` attribute on that module. -#. For modules which are also packages, the module namespace SHOULD +#. For modules which are also packages, the module's namespace SHOULD include the ``__version__`` attribute. #. For modules which live inside a namespace package, the sub-package @@ -225,7 +225,7 @@ [metadata] version-from-file: elle.py -where ``parse`` means to use a parsing method similar to the above, on +A parsing method similar to that described above will be performed on the file named after the colon. The exact recipe for doing this will be discussed in the appropriate distutils2 development forum. -- Repository URL: http://hg.python.org/peps From solipsis at pitrou.net Wed Jun 8 05:07:39 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 08 Jun 2011 05:07:39 +0200 Subject: [Python-checkins] Daily reference leaks (5392be94ea65): sum=399 Message-ID: results for 5392be94ea65 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogEF6AJX', '-x'] From python-checkins at python.org Wed Jun 8 05:09:39 2011 From: python-checkins at python.org (brett.cannon) Date: Wed, 08 Jun 2011 05:09:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Revert_a_reversed_compariso?= =?utf8?q?n_order_introduced_in_r70695=2E?= Message-ID: http://hg.python.org/cpython/rev/8587305b259b changeset: 70710:8587305b259b user: Brett Cannon date: Tue Jun 07 20:09:32 2011 -0700 summary: Revert a reversed comparison order introduced in r70695. files: Modules/arraymodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2091,7 +2091,7 @@ if (len == 0) { return PyUnicode_FromFormat("array('%c')", (int)typecode); } - if ('u' == typecode) + if (typecode == 'u') v = array_tounicode(a, NULL); else v = array_tolist(a, NULL); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 8 17:23:28 2011 From: python-checkins at python.org (antoine.pitrou) Date: Wed, 08 Jun 2011 17:23:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=239205=3A_concurrent?= =?utf8?q?=2Efutures=2EProcessPoolExecutor_now_detects_killed?= Message-ID: http://hg.python.org/cpython/rev/6d6099f7fe89 changeset: 70711:6d6099f7fe89 user: Antoine Pitrou date: Wed Jun 08 17:21:55 2011 +0200 summary: Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed children and raises BrokenProcessPool in such a situation. Previously it would reliably freeze/deadlock. files: Doc/library/concurrent.futures.rst | 19 + Lib/concurrent/futures/process.py | 105 +- Lib/multiprocessing/connection.py | 149 ++- Lib/multiprocessing/forking.py | 1 + Lib/multiprocessing/queues.py | 6 +- Lib/test/test_concurrent_futures.py | 20 +- Misc/NEWS | 4 + Modules/_multiprocessing/win32_functions.c | 390 +++++++++- 8 files changed, 587 insertions(+), 107 deletions(-) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -169,6 +169,12 @@ of at most *max_workers* processes. If *max_workers* is ``None`` or not given, it will default to the number of processors on the machine. + .. versionchanged:: 3.3 + When one of the worker processes terminates abruptly, a + :exc:`BrokenProcessPool` error is now raised. Previously, behaviour + was undefined but operations on the executor or its futures would often + freeze or deadlock. + .. _processpoolexecutor-example: @@ -369,3 +375,16 @@ :pep:`3148` -- futures - execute computations asynchronously The proposal which described this feature for inclusion in the Python standard library. + + +Exception classes +----------------- + +.. exception:: BrokenProcessPool + + Derived from :exc:`RuntimeError`, this exception class is raised when + one of the workers of a :class:`ProcessPoolExecutor` has terminated + in a non-clean fashion (for example, if it was killed from the outside). + + .. versionadded:: 3.3 + diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -46,10 +46,11 @@ __author__ = 'Brian Quinlan (brian at sweetapp.com)' import atexit +import os from concurrent.futures import _base import queue import multiprocessing -from multiprocessing.queues import SimpleQueue +from multiprocessing.queues import SimpleQueue, SentinelReady import threading import weakref @@ -122,7 +123,7 @@ call_item = call_queue.get(block=True) if call_item is None: # Wake up queue management thread - result_queue.put(None) + result_queue.put(os.getpid()) return try: r = call_item.fn(*call_item.args, **call_item.kwargs) @@ -194,29 +195,63 @@ result_queue: A multiprocessing.Queue of _ResultItems generated by the process workers. """ - nb_shutdown_processes = 0 - def shutdown_one_process(): - """Tell a worker to terminate, which will in turn wake us again""" - nonlocal nb_shutdown_processes - call_queue.put(None) - nb_shutdown_processes += 1 + + def shutdown_worker(): + # This is an upper bound + nb_children_alive = sum(p.is_alive() for p in processes.values()) + for i in range(0, nb_children_alive): + call_queue.put(None) + # If .join() is not called on the created processes then + # some multiprocessing.Queue methods may deadlock on Mac OS + # X. + for p in processes.values(): + p.join() + while True: _add_call_item_to_queue(pending_work_items, work_ids_queue, call_queue) - result_item = result_queue.get() - if result_item is not None: - work_item = pending_work_items[result_item.work_id] - del pending_work_items[result_item.work_id] - - if result_item.exception: - work_item.future.set_exception(result_item.exception) - else: - work_item.future.set_result(result_item.result) - continue - # If we come here, we either got a timeout or were explicitly woken up. - # In either case, check whether we should start shutting down. + sentinels = [p.sentinel for p in processes.values()] + assert sentinels + try: + result_item = result_queue.get(sentinels=sentinels) + except SentinelReady as e: + # Mark the process pool broken so that submits fail right now. + executor = executor_reference() + if executor is not None: + executor._broken = True + executor._shutdown_thread = True + del executor + # All futures in flight must be marked failed + for work_id, work_item in pending_work_items.items(): + work_item.future.set_exception( + BrokenProcessPool( + "A process in the process pool was " + "terminated abruptly while the future was " + "running or pending." + )) + pending_work_items.clear() + # Terminate remaining workers forcibly: the queues or their + # locks may be in a dirty state and block forever. + for p in processes.values(): + p.terminate() + for p in processes.values(): + p.join() + return + if isinstance(result_item, int): + # Clean shutdown of a worker using its PID + # (avoids marking the executor broken) + del processes[result_item] + elif result_item is not None: + work_item = pending_work_items.pop(result_item.work_id, None) + # work_item can be None if another process terminated (see above) + if work_item is not None: + if result_item.exception: + work_item.future.set_exception(result_item.exception) + else: + work_item.future.set_result(result_item.result) + # Check whether we should start shutting down. executor = executor_reference() # No more work items can be added if: # - The interpreter is shutting down OR @@ -226,17 +261,11 @@ # Since no new work items can be added, it is safe to shutdown # this thread if there are no pending work items. if not pending_work_items: - while nb_shutdown_processes < len(processes): - shutdown_one_process() - # If .join() is not called on the created processes then - # some multiprocessing.Queue methods may deadlock on Mac OS - # X. - for p in processes: - p.join() + shutdown_worker() return else: # Start shutting down by telling a process it can exit. - shutdown_one_process() + call_queue.put(None) del executor _system_limits_checked = False @@ -264,6 +293,14 @@ _system_limited = "system provides too few semaphores (%d available, 256 necessary)" % nsems_max raise NotImplementedError(_system_limited) + +class BrokenProcessPool(RuntimeError): + """ + Raised when a process in a ProcessPoolExecutor terminated abruptly + while a future was in the running state. + """ + + class ProcessPoolExecutor(_base.Executor): def __init__(self, max_workers=None): """Initializes a new ProcessPoolExecutor instance. @@ -288,11 +325,13 @@ self._result_queue = SimpleQueue() self._work_ids = queue.Queue() self._queue_management_thread = None - self._processes = set() + # Map of pids to processes + self._processes = {} # Shutdown is a two-step process. self._shutdown_thread = False self._shutdown_lock = threading.Lock() + self._broken = False self._queue_count = 0 self._pending_work_items = {} @@ -302,6 +341,8 @@ def weakref_cb(_, q=self._result_queue): q.put(None) if self._queue_management_thread is None: + # Start the processes so that their sentinels are known. + self._adjust_process_count() self._queue_management_thread = threading.Thread( target=_queue_management_worker, args=(weakref.ref(self, weakref_cb), @@ -321,10 +362,13 @@ args=(self._call_queue, self._result_queue)) p.start() - self._processes.add(p) + self._processes[p.pid] = p def submit(self, fn, *args, **kwargs): with self._shutdown_lock: + if self._broken: + raise BrokenProcessPool('A child process terminated ' + 'abruptly, the process pool is not usable anymore') if self._shutdown_thread: raise RuntimeError('cannot schedule new futures after shutdown') @@ -338,7 +382,6 @@ self._result_queue.put(None) self._start_queue_management_thread() - self._adjust_process_count() return f submit.__doc__ = _base.Executor.submit.__doc__ diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -48,14 +48,18 @@ import _multiprocessing from multiprocessing import current_process, AuthenticationError, BufferTooShort -from multiprocessing.util import get_temp_dir, Finalize, sub_debug, debug +from multiprocessing.util import ( + get_temp_dir, Finalize, sub_debug, debug, _eintr_retry) try: from _multiprocessing import win32 + from _subprocess import WAIT_OBJECT_0, WAIT_TIMEOUT, INFINITE except ImportError: if sys.platform == 'win32': raise win32 = None +_select = _eintr_retry(select.select) + # # # @@ -118,6 +122,15 @@ else: raise ValueError('address type of %r unrecognized' % address) + +class SentinelReady(Exception): + """ + Raised when a sentinel is ready when polling. + """ + def __init__(self, *args): + Exception.__init__(self, *args) + self.sentinels = args[0] + # # Connection classes # @@ -253,19 +266,17 @@ (offset + size) // itemsize]) return size - def recv(self): + def recv(self, sentinels=None): """Receive a (picklable) object""" self._check_closed() self._check_readable() - buf = self._recv_bytes() + buf = self._recv_bytes(sentinels=sentinels) return pickle.loads(buf.getbuffer()) def poll(self, timeout=0.0): """Whether there is any input available to be read""" self._check_closed() self._check_readable() - if timeout < 0.0: - timeout = None return self._poll(timeout) @@ -274,61 +285,88 @@ class PipeConnection(_ConnectionBase): """ Connection class based on a Windows named pipe. + Overlapped I/O is used, so the handles must have been created + with FILE_FLAG_OVERLAPPED. """ + _buffered = b'' def _close(self): win32.CloseHandle(self._handle) def _send_bytes(self, buf): - nwritten = win32.WriteFile(self._handle, buf) + overlapped = win32.WriteFile(self._handle, buf, overlapped=True) + nwritten, complete = overlapped.GetOverlappedResult(True) + assert complete assert nwritten == len(buf) - def _recv_bytes(self, maxsize=None): + def _recv_bytes(self, maxsize=None, sentinels=()): + if sentinels: + self._poll(-1.0, sentinels) buf = io.BytesIO() - bufsize = 512 - if maxsize is not None: - bufsize = min(bufsize, maxsize) - try: - firstchunk, complete = win32.ReadFile(self._handle, bufsize) - except IOError as e: - if e.errno == win32.ERROR_BROKEN_PIPE: - raise EOFError - raise - lenfirstchunk = len(firstchunk) - buf.write(firstchunk) - if complete: - return buf + firstchunk = self._buffered + if firstchunk: + lenfirstchunk = len(firstchunk) + buf.write(firstchunk) + self._buffered = b'' + else: + # A reasonable size for the first chunk transfer + bufsize = 128 + if maxsize is not None and maxsize < bufsize: + bufsize = maxsize + try: + overlapped = win32.ReadFile(self._handle, bufsize, overlapped=True) + lenfirstchunk, complete = overlapped.GetOverlappedResult(True) + firstchunk = overlapped.getbuffer() + assert lenfirstchunk == len(firstchunk) + except IOError as e: + if e.errno == win32.ERROR_BROKEN_PIPE: + raise EOFError + raise + buf.write(firstchunk) + if complete: + return buf navail, nleft = win32.PeekNamedPipe(self._handle) if maxsize is not None and lenfirstchunk + nleft > maxsize: return None - lastchunk, complete = win32.ReadFile(self._handle, nleft) - assert complete - buf.write(lastchunk) + if nleft > 0: + overlapped = win32.ReadFile(self._handle, nleft, overlapped=True) + res, complete = overlapped.GetOverlappedResult(True) + assert res == nleft + assert complete + buf.write(overlapped.getbuffer()) return buf - def _poll(self, timeout): + def _poll(self, timeout, sentinels=()): + # Fast non-blocking path navail, nleft = win32.PeekNamedPipe(self._handle) if navail > 0: return True elif timeout == 0.0: return False - # Setup a polling loop (translated straight from old - # pipe_connection.c) + # Blocking: use overlapped I/O if timeout < 0.0: - deadline = None + timeout = INFINITE else: - deadline = time.time() + timeout - delay = 0.001 - max_delay = 0.02 - while True: - time.sleep(delay) - navail, nleft = win32.PeekNamedPipe(self._handle) - if navail > 0: - return True - if deadline and time.time() > deadline: - return False - if delay < max_delay: - delay += 0.001 + timeout = int(timeout * 1000 + 0.5) + overlapped = win32.ReadFile(self._handle, 1, overlapped=True) + try: + handles = [overlapped.event] + handles += sentinels + res = win32.WaitForMultipleObjects(handles, False, timeout) + finally: + # Always cancel overlapped I/O in the same thread + # (because CancelIoEx() appears only in Vista) + overlapped.cancel() + if res == WAIT_TIMEOUT: + return False + idx = res - WAIT_OBJECT_0 + if idx == 0: + # I/O was successful, store received data + overlapped.GetOverlappedResult(True) + self._buffered += overlapped.getbuffer() + return True + assert 0 < idx < len(handles) + raise SentinelReady([handles[idx]]) class Connection(_ConnectionBase): @@ -357,11 +395,18 @@ break buf = buf[n:] - def _recv(self, size, read=_read): + def _recv(self, size, sentinels=(), read=_read): buf = io.BytesIO() + handle = self._handle + if sentinels: + handles = [handle] + sentinels remaining = size while remaining > 0: - chunk = read(self._handle, remaining) + if sentinels: + r = _select(handles, [], [])[0] + if handle not in r: + raise SentinelReady(r) + chunk = read(handle, remaining) n = len(chunk) if n == 0: if remaining == size: @@ -381,15 +426,17 @@ if n > 0: self._send(buf) - def _recv_bytes(self, maxsize=None): - buf = self._recv(4) + def _recv_bytes(self, maxsize=None, sentinels=()): + buf = self._recv(4, sentinels) size, = struct.unpack("=i", buf.getvalue()) if maxsize is not None and size > maxsize: return None - return self._recv(size) + return self._recv(size, sentinels) def _poll(self, timeout): - r = select.select([self._handle], [], [], timeout)[0] + if timeout < 0.0: + timeout = None + r = _select([self._handle], [], [], timeout)[0] return bool(r) @@ -495,23 +542,21 @@ obsize, ibsize = 0, BUFSIZE h1 = win32.CreateNamedPipe( - address, openmode, + address, openmode | win32.FILE_FLAG_OVERLAPPED, win32.PIPE_TYPE_MESSAGE | win32.PIPE_READMODE_MESSAGE | win32.PIPE_WAIT, 1, obsize, ibsize, win32.NMPWAIT_WAIT_FOREVER, win32.NULL ) h2 = win32.CreateFile( - address, access, 0, win32.NULL, win32.OPEN_EXISTING, 0, win32.NULL + address, access, 0, win32.NULL, win32.OPEN_EXISTING, + win32.FILE_FLAG_OVERLAPPED, win32.NULL ) win32.SetNamedPipeHandleState( h2, win32.PIPE_READMODE_MESSAGE, None, None ) - try: - win32.ConnectNamedPipe(h1, win32.NULL) - except WindowsError as e: - if e.args[0] != win32.ERROR_PIPE_CONNECTED: - raise + overlapped = win32.ConnectNamedPipe(h1, overlapped=True) + overlapped.GetOverlappedResult(True) c1 = PipeConnection(h1, writable=duplex) c2 = PipeConnection(h2, readable=duplex) diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py --- a/Lib/multiprocessing/forking.py +++ b/Lib/multiprocessing/forking.py @@ -35,6 +35,7 @@ import os import sys import signal +import select from multiprocessing import util, process diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -44,7 +44,7 @@ from queue import Empty, Full import _multiprocessing -from multiprocessing import Pipe +from multiprocessing.connection import Pipe, SentinelReady from multiprocessing.synchronize import Lock, BoundedSemaphore, Semaphore, Condition from multiprocessing.util import debug, info, Finalize, register_after_fork from multiprocessing.forking import assert_spawning @@ -372,10 +372,10 @@ def _make_methods(self): recv = self._reader.recv racquire, rrelease = self._rlock.acquire, self._rlock.release - def get(): + def get(*, sentinels=None): racquire() try: - return recv() + return recv(sentinels) finally: rrelease() self.get = get diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -19,7 +19,7 @@ from concurrent import futures from concurrent.futures._base import ( PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future) -import concurrent.futures.process +from concurrent.futures.process import BrokenProcessPool def create_future(state=PENDING, exception=None, result=None): @@ -154,7 +154,7 @@ processes = self.executor._processes self.executor.shutdown() - for p in processes: + for p in processes.values(): p.join() def test_context_manager_shutdown(self): @@ -163,7 +163,7 @@ self.assertEqual(list(e.map(abs, range(-5, 5))), [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - for p in processes: + for p in processes.values(): p.join() def test_del_shutdown(self): @@ -174,7 +174,7 @@ del executor queue_management_thread.join() - for p in processes: + for p in processes.values(): p.join() class WaitTests(unittest.TestCase): @@ -381,7 +381,17 @@ class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest): - pass + def test_killed_child(self): + # When a child process is abruptly terminated, the whole pool gets + # "broken". + futures = [self.executor.submit(time.sleep, 3)] + # Get one of the processes, and terminate (kill) it + p = next(iter(self.executor._processes.values())) + p.terminate() + for fut in futures: + self.assertRaises(BrokenProcessPool, fut.result) + # Submitting other jobs fails as well. + self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) class FutureTests(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,10 @@ Library ------- +- Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed + children and raises BrokenProcessPool in such a situation. Previously it + would reliably freeze/deadlock. + - Issue #12040: Expose a new attribute ``sentinel`` on instances of :class:`multiprocessing.Process`. Also, fix Process.join() to not use polling anymore, when given a timeout. diff --git a/Modules/_multiprocessing/win32_functions.c b/Modules/_multiprocessing/win32_functions.c --- a/Modules/_multiprocessing/win32_functions.c +++ b/Modules/_multiprocessing/win32_functions.c @@ -12,10 +12,223 @@ #define WIN32_FUNCTION(func) \ {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""} +#define WIN32_KWARGS_FUNCTION(func) \ + {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_KEYWORDS | METH_STATIC, ""} + #define WIN32_CONSTANT(fmt, con) \ PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con)) +/* Grab CancelIoEx dynamically from kernel32 */ +static int has_CancelIoEx = -1; +static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED); + +static int +check_CancelIoEx() +{ + if (has_CancelIoEx == -1) + { + HINSTANCE hKernel32 = GetModuleHandle("KERNEL32"); + * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32, + "CancelIoEx"); + has_CancelIoEx = (Py_CancelIoEx != NULL); + } + return has_CancelIoEx; +} + + +/* + * A Python object wrapping an OVERLAPPED structure and other useful data + * for overlapped I/O + */ + +typedef struct { + PyObject_HEAD + OVERLAPPED overlapped; + /* For convenience, we store the file handle too */ + HANDLE handle; + /* Whether there's I/O in flight */ + int pending; + /* Whether I/O completed successfully */ + int completed; + /* Buffer used for reading (optional) */ + PyObject *read_buffer; + /* Buffer used for writing (optional) */ + Py_buffer write_buffer; +} OverlappedObject; + +static void +overlapped_dealloc(OverlappedObject *self) +{ + int err = GetLastError(); + if (self->pending) { + if (check_CancelIoEx()) + Py_CancelIoEx(self->handle, &self->overlapped); + else { + PyErr_SetString(PyExc_RuntimeError, + "I/O operations still in flight while destroying " + "Overlapped object, the process may crash"); + PyErr_WriteUnraisable(NULL); + } + } + CloseHandle(self->overlapped.hEvent); + SetLastError(err); + if (self->write_buffer.obj) + PyBuffer_Release(&self->write_buffer); + Py_CLEAR(self->read_buffer); + PyObject_Del(self); +} + +static PyObject * +overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj) +{ + int wait; + BOOL res; + DWORD transferred = 0; + + wait = PyObject_IsTrue(waitobj); + if (wait < 0) + return NULL; + Py_BEGIN_ALLOW_THREADS + res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, + wait != 0); + Py_END_ALLOW_THREADS + + if (!res) { + int err = GetLastError(); + if (err == ERROR_IO_INCOMPLETE) + Py_RETURN_NONE; + if (err != ERROR_MORE_DATA) { + self->pending = 0; + return PyErr_SetExcFromWindowsErr(PyExc_IOError, err); + } + } + self->pending = 0; + self->completed = 1; + if (self->read_buffer) { + assert(PyBytes_CheckExact(self->read_buffer)); + if (_PyBytes_Resize(&self->read_buffer, transferred)) + return NULL; + } + return Py_BuildValue("lN", (long) transferred, PyBool_FromLong(res)); +} + +static PyObject * +overlapped_getbuffer(OverlappedObject *self) +{ + PyObject *res; + if (!self->completed) { + PyErr_SetString(PyExc_ValueError, + "can't get read buffer before GetOverlappedResult() " + "signals the operation completed"); + return NULL; + } + res = self->read_buffer ? self->read_buffer : Py_None; + Py_INCREF(res); + return res; +} + +static PyObject * +overlapped_cancel(OverlappedObject *self) +{ + BOOL res = TRUE; + + if (self->pending) { + Py_BEGIN_ALLOW_THREADS + if (check_CancelIoEx()) + res = Py_CancelIoEx(self->handle, &self->overlapped); + else + res = CancelIo(self->handle); + Py_END_ALLOW_THREADS + } + + /* CancelIoEx returns ERROR_NOT_FOUND if the I/O completed in-between */ + if (!res && GetLastError() != ERROR_NOT_FOUND) + return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); + self->pending = 0; + Py_RETURN_NONE; +} + +static PyMethodDef overlapped_methods[] = { + {"GetOverlappedResult", (PyCFunction) overlapped_GetOverlappedResult, + METH_O, NULL}, + {"getbuffer", (PyCFunction) overlapped_getbuffer, METH_NOARGS, NULL}, + {"cancel", (PyCFunction) overlapped_cancel, METH_NOARGS, NULL}, + {NULL} +}; + +static PyMemberDef overlapped_members[] = { + {"event", T_HANDLE, + offsetof(OverlappedObject, overlapped) + offsetof(OVERLAPPED, hEvent), + READONLY, "overlapped event handle"}, + {NULL} +}; + +PyTypeObject OverlappedType = { + PyVarObject_HEAD_INIT(NULL, 0) + /* tp_name */ "_multiprocessing.win32.Overlapped", + /* tp_basicsize */ sizeof(OverlappedObject), + /* tp_itemsize */ 0, + /* tp_dealloc */ (destructor) overlapped_dealloc, + /* tp_print */ 0, + /* tp_getattr */ 0, + /* tp_setattr */ 0, + /* tp_reserved */ 0, + /* tp_repr */ 0, + /* tp_as_number */ 0, + /* tp_as_sequence */ 0, + /* tp_as_mapping */ 0, + /* tp_hash */ 0, + /* tp_call */ 0, + /* tp_str */ 0, + /* tp_getattro */ 0, + /* tp_setattro */ 0, + /* tp_as_buffer */ 0, + /* tp_flags */ Py_TPFLAGS_DEFAULT, + /* tp_doc */ "OVERLAPPED structure wrapper", + /* tp_traverse */ 0, + /* tp_clear */ 0, + /* tp_richcompare */ 0, + /* tp_weaklistoffset */ 0, + /* tp_iter */ 0, + /* tp_iternext */ 0, + /* tp_methods */ overlapped_methods, + /* tp_members */ overlapped_members, + /* tp_getset */ 0, + /* tp_base */ 0, + /* tp_dict */ 0, + /* tp_descr_get */ 0, + /* tp_descr_set */ 0, + /* tp_dictoffset */ 0, + /* tp_init */ 0, + /* tp_alloc */ 0, + /* tp_new */ 0, +}; + +static OverlappedObject * +new_overlapped(HANDLE handle) +{ + OverlappedObject *self; + + self = PyObject_New(OverlappedObject, &OverlappedType); + if (!self) + return NULL; + self->handle = handle; + self->read_buffer = NULL; + self->pending = 0; + self->completed = 0; + memset(&self->overlapped, 0, sizeof(OVERLAPPED)); + memset(&self->write_buffer, 0, sizeof(Py_buffer)); + /* Manual reset, initially non-signalled */ + self->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return self; +} + + +/* + * Module functions + */ + static PyObject * win32_CloseHandle(PyObject *self, PyObject *args) { @@ -36,20 +249,44 @@ } static PyObject * -win32_ConnectNamedPipe(PyObject *self, PyObject *args) +win32_ConnectNamedPipe(PyObject *self, PyObject *args, PyObject *kwds) { HANDLE hNamedPipe; - LPOVERLAPPED lpOverlapped; + int use_overlapped = 0; BOOL success; + OverlappedObject *overlapped = NULL; + static char *kwlist[] = {"handle", "overlapped", NULL}; - if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER, - &hNamedPipe, &lpOverlapped)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + F_HANDLE "|i", kwlist, + &hNamedPipe, &use_overlapped)) return NULL; + if (use_overlapped) { + overlapped = new_overlapped(hNamedPipe); + if (!overlapped) + return NULL; + } + Py_BEGIN_ALLOW_THREADS - success = ConnectNamedPipe(hNamedPipe, lpOverlapped); + success = ConnectNamedPipe(hNamedPipe, + overlapped ? &overlapped->overlapped : NULL); Py_END_ALLOW_THREADS + if (overlapped) { + int err = GetLastError(); + /* Overlapped ConnectNamedPipe never returns a success code */ + assert(success == 0); + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else if (err == ERROR_PIPE_CONNECTED) + SetEvent(overlapped->overlapped.hEvent); + else { + Py_DECREF(overlapped); + return PyErr_SetFromWindowsErr(err); + } + return (PyObject *) overlapped; + } if (!success) return PyErr_SetFromWindowsErr(0); @@ -280,46 +517,109 @@ } static PyObject * -win32_WriteFile(PyObject *self, PyObject *args) +win32_WriteFile(PyObject *self, PyObject *args, PyObject *kwds) { HANDLE handle; - Py_buffer buf; + Py_buffer _buf, *buf; + PyObject *bufobj; int written; BOOL ret; + int use_overlapped = 0; + OverlappedObject *overlapped = NULL; + static char *kwlist[] = {"handle", "buffer", "overlapped", NULL}; - if (!PyArg_ParseTuple(args, F_HANDLE "y*:WriteFile" , &handle, &buf)) + /* First get handle and use_overlapped to know which Py_buffer to use */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, + F_HANDLE "O|i:WriteFile", kwlist, + &handle, &bufobj, &use_overlapped)) return NULL; + if (use_overlapped) { + overlapped = new_overlapped(handle); + if (!overlapped) + return NULL; + buf = &overlapped->write_buffer; + } + else + buf = &_buf; + + if (!PyArg_Parse(bufobj, "y*", buf)) { + Py_XDECREF(overlapped); + return NULL; + } + Py_BEGIN_ALLOW_THREADS - ret = WriteFile(handle, buf.buf, buf.len, &written, NULL); + ret = WriteFile(handle, buf->buf, buf->len, &written, + overlapped ? &overlapped->overlapped : NULL); Py_END_ALLOW_THREADS - PyBuffer_Release(&buf); + if (overlapped) { + int err = GetLastError(); + if (!ret) { + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else { + Py_DECREF(overlapped); + return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); + } + } + return (PyObject *) overlapped; + } + + PyBuffer_Release(buf); if (!ret) return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); return PyLong_FromLong(written); } static PyObject * -win32_ReadFile(PyObject *self, PyObject *args) +win32_ReadFile(PyObject *self, PyObject *args, PyObject *kwds) { HANDLE handle; int size; DWORD nread; PyObject *buf; BOOL ret; + int use_overlapped = 0; + OverlappedObject *overlapped = NULL; + static char *kwlist[] = {"handle", "size", "overlapped", NULL}; - if (!PyArg_ParseTuple(args, F_HANDLE "i:ReadFile" , &handle, &size)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + F_HANDLE "i|i:ReadFile", kwlist, + &handle, &size, &use_overlapped)) return NULL; buf = PyBytes_FromStringAndSize(NULL, size); if (!buf) return NULL; + if (use_overlapped) { + overlapped = new_overlapped(handle); + if (!overlapped) { + Py_DECREF(buf); + return NULL; + } + /* Steals reference to buf */ + overlapped->read_buffer = buf; + } Py_BEGIN_ALLOW_THREADS - ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread, NULL); + ret = ReadFile(handle, PyBytes_AS_STRING(buf), size, &nread, + overlapped ? &overlapped->overlapped : NULL); Py_END_ALLOW_THREADS + if (overlapped) { + int err = GetLastError(); + if (!ret) { + if (err == ERROR_IO_PENDING) + overlapped->pending = 1; + else if (err != ERROR_MORE_DATA) { + Py_DECREF(overlapped); + return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); + } + } + return (PyObject *) overlapped; + } + if (!ret && GetLastError() != ERROR_MORE_DATA) { Py_DECREF(buf); return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); @@ -373,19 +673,71 @@ } } +static PyObject * +win32_WaitForMultipleObjects(PyObject* self, PyObject* args) +{ + DWORD result; + PyObject *handle_seq; + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + Py_ssize_t nhandles, i; + int wait_flag; + int milliseconds = INFINITE; + + if (!PyArg_ParseTuple(args, "Oi|i:WaitForMultipleObjects", + &handle_seq, &wait_flag, &milliseconds)) + return NULL; + + if (!PySequence_Check(handle_seq)) { + PyErr_Format(PyExc_TypeError, + "sequence type expected, got '%s'", + Py_TYPE(handle_seq)->tp_doc); + return NULL; + } + nhandles = PySequence_Length(handle_seq); + if (nhandles == -1) + return NULL; + if (nhandles < 0 || nhandles >= MAXIMUM_WAIT_OBJECTS) { + PyErr_Format(PyExc_ValueError, + "need at most %zd handles, got a sequence of length %zd", + MAXIMUM_WAIT_OBJECTS, nhandles); + return NULL; + } + for (i = 0; i < nhandles; i++) { + HANDLE h; + PyObject *v = PySequence_GetItem(handle_seq, i); + if (v == NULL) + return NULL; + if (!PyArg_Parse(v, F_HANDLE, &h)) + return NULL; + handles[i] = h; + } + + Py_BEGIN_ALLOW_THREADS + result = WaitForMultipleObjects((DWORD) nhandles, handles, + (BOOL) wait_flag, (DWORD) milliseconds); + Py_END_ALLOW_THREADS + + if (result == WAIT_FAILED) + return PyErr_SetExcFromWindowsErr(PyExc_IOError, 0); + + return PyLong_FromLong((int) result); +} + + static PyMethodDef win32_methods[] = { WIN32_FUNCTION(CloseHandle), WIN32_FUNCTION(GetLastError), WIN32_FUNCTION(OpenProcess), WIN32_FUNCTION(ExitProcess), - WIN32_FUNCTION(ConnectNamedPipe), + WIN32_KWARGS_FUNCTION(ConnectNamedPipe), WIN32_FUNCTION(CreateFile), WIN32_FUNCTION(CreateNamedPipe), - WIN32_FUNCTION(ReadFile), + WIN32_KWARGS_FUNCTION(ReadFile), WIN32_FUNCTION(PeekNamedPipe), WIN32_FUNCTION(SetNamedPipeHandleState), + WIN32_FUNCTION(WaitForMultipleObjects), WIN32_FUNCTION(WaitNamedPipe), - WIN32_FUNCTION(WriteFile), + WIN32_KWARGS_FUNCTION(WriteFile), WIN32_FUNCTION(closesocket), WIN32_FUNCTION(recv), WIN32_FUNCTION(send), @@ -407,12 +759,18 @@ return NULL; Py_INCREF(&Win32Type); + if (PyType_Ready(&OverlappedType) < 0) + return NULL; + PyDict_SetItemString(Win32Type.tp_dict, "Overlapped", + (PyObject *) &OverlappedType); + WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS); WIN32_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE); WIN32_CONSTANT(F_DWORD, ERROR_NO_SYSTEM_RESOURCES); WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED); WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); + WIN32_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED); WIN32_CONSTANT(F_DWORD, GENERIC_READ); WIN32_CONSTANT(F_DWORD, GENERIC_WRITE); WIN32_CONSTANT(F_DWORD, INFINITE); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 8 19:18:35 2011 From: python-checkins at python.org (charles-francois.natali) Date: Wed, 08 Jun 2011 19:18:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312021=3A_Make_mmap?= =?utf8?q?=27s_read=28=29_method_argument_optional=2E_Patch_by_Petri?= Message-ID: http://hg.python.org/cpython/rev/964d0d65a2a9 changeset: 70712:964d0d65a2a9 user: Charles-Fran?ois Natali date: Wed Jun 08 19:18:14 2011 +0200 summary: Issue #12021: Make mmap's read() method argument optional. Patch by Petri Lehtinen. files: Doc/library/mmap.rst | 12 ++++++++---- Lib/test/test_mmap.py | 29 +++++++++++++++++++++++++++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/mmapmodule.c | 26 ++++++++++++++++++++++++-- 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -190,12 +190,16 @@ move will raise a :exc:`TypeError` exception. - .. method:: read(num) + .. method:: read([n]) - Return a :class:`bytes` containing up to *num* bytes starting from the - current file position; the file position is updated to point after the - bytes that were returned. + Return a :class:`bytes` containing up to *n* bytes starting from the + current file position. If the argument is omitted, *None* or negative, + return all bytes from the current file position to the end of the + mapping. The file position is updated to point after the bytes that were + returned. + .. versionchanged:: 3.3 + Argument can be omitted or *None*. .. method:: read_byte() diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -417,6 +417,35 @@ m[x] = b self.assertEqual(m[x], b) + def test_read_all(self): + m = mmap.mmap(-1, 16) + self.addCleanup(m.close) + + # With no parameters, or None or a negative argument, reads all + m.write(bytes(range(16))) + m.seek(0) + self.assertEqual(m.read(), bytes(range(16))) + m.seek(8) + self.assertEqual(m.read(), bytes(range(8, 16))) + m.seek(16) + self.assertEqual(m.read(), b'') + m.seek(3) + self.assertEqual(m.read(None), bytes(range(3, 16))) + m.seek(4) + self.assertEqual(m.read(-1), bytes(range(4, 16))) + m.seek(5) + self.assertEqual(m.read(-2), bytes(range(5, 16))) + m.seek(9) + self.assertEqual(m.read(-42), bytes(range(9, 16))) + + def test_read_invalid_arg(self): + m = mmap.mmap(-1, 16) + self.addCleanup(m.close) + + self.assertRaises(TypeError, m.read, 'foo') + self.assertRaises(TypeError, m.read, 5.5) + self.assertRaises(TypeError, m.read, [1, 2, 3]) + def test_extended_getslice(self): # Test extended slicing by comparing with list slicing. s = bytes(reversed(range(256))) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -548,6 +548,7 @@ Kip Lehman Joerg Lehmann Robert Lehmann +Petri Lehtinen Luke Kenneth Casson Leighton Marc-Andre Lemburg John Lenton diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #12021: Make mmap's read() method argument optional. Patch by Petri + Lehtinen. + - Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed children and raises BrokenProcessPool in such a situation. Previously it would reliably freeze/deadlock. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -240,15 +240,37 @@ return result; } +/* Basically the "n" format code with the ability to turn None into -1. */ +static int +mmap_convert_ssize_t(PyObject *obj, void *result) { + Py_ssize_t limit; + if (obj == Py_None) { + limit = -1; + } + else if (PyNumber_Check(obj)) { + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "integer argument expected, got '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + static PyObject * mmap_read_method(mmap_object *self, PyObject *args) { - Py_ssize_t num_bytes, n; + Py_ssize_t num_bytes = -1, n; PyObject *result; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "n:read", &num_bytes)) + if (!PyArg_ParseTuple(args, "|O&:read", mmap_convert_ssize_t, &num_bytes)) return(NULL); /* silently 'adjust' out-of-range requests */ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 02:00:27 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 02:00:27 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogRml4ICMxMTU4My4g?= =?utf8?q?Changed_os=2Epath=2Eisdir_to_use_GetFileAttributes_instead_of_os?= =?utf8?b?LnN0YXQu?= Message-ID: http://hg.python.org/cpython/rev/88e318166eaf changeset: 70713:88e318166eaf branch: 3.2 parent: 70700:0aa3064d1cef user: Brian Curtin date: Wed Jun 08 18:17:18 2011 -0500 summary: Fix #11583. Changed os.path.isdir to use GetFileAttributes instead of os.stat. By changing to the Windows GetFileAttributes API in nt._isdir we can figure out if the path is a directory without opening the file via os.stat. This has the minor benefit of speeding up os.path.isdir by at least 2x for regular files and 10-15x improvements were seen on symbolic links (which opened the file multiple times during os.stat). Since os.path.isdir is used in several places on interpreter startup, we get a minor speedup in startup time. files: Lib/ntpath.py | 13 ++++++++++ Misc/NEWS | 3 ++ Modules/posixmodule.c | 37 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 0 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -672,3 +672,16 @@ def sameopenfile(f1, f2): """Test whether two file objects reference the same file""" return _getfileinformation(f1) == _getfileinformation(f2) + + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir +except ImportError: + from genericpath import isdir as _isdir + +def isdir(path): + return _isdir(path) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Library ------- +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Named tuples now work correctly with vars(). - Issue #12085: Fix an attribute error in subprocess.Popen destructor if the diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2819,6 +2819,42 @@ info.nFileIndexHigh, info.nFileIndexLow); } + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "O&:_isdir", + PyUnicode_FSConverter, &opath)) + return NULL; + + path = PyBytes_AsString(opath); + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ PyDoc_STRVAR(posix_mkdir__doc__, @@ -8055,6 +8091,7 @@ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, NULL}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 02:00:27 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 02:00:27 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Fix_=2311583=2E_Changed_os=2Epath=2Eisdir_to_use_GetFileAttr?= =?utf8?q?ibutes_instead_of_os=2Estat=2E?= Message-ID: http://hg.python.org/cpython/rev/567f30527913 changeset: 70714:567f30527913 parent: 70712:964d0d65a2a9 parent: 70713:88e318166eaf user: Brian Curtin date: Wed Jun 08 18:43:57 2011 -0500 summary: Fix #11583. Changed os.path.isdir to use GetFileAttributes instead of os.stat. By changing to the Windows GetFileAttributes API in nt._isdir we can figure out if the path is a directory without opening the file via os.stat. This has the minor benefit of speeding up os.path.isdir by at least 2x for regular files and 10-15x improvements were seen on symbolic links (which opened the file multiple times during os.stat). Since os.path.isdir is used in several places on interpreter startup, we get a minor speedup in startup time. files: Lib/ntpath.py | 13 ++++++++++ Misc/NEWS | 3 ++ Modules/posixmodule.c | 37 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 0 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -672,3 +672,16 @@ def sameopenfile(f1, f2): """Test whether two file objects reference the same file""" return _getfileinformation(f1) == _getfileinformation(f2) + + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir +except ImportError: + from genericpath import isdir as _isdir + +def isdir(path): + return _isdir(path) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Issue #12021: Make mmap's read() method argument optional. Patch by Petri Lehtinen. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2960,6 +2960,42 @@ info.nFileIndexHigh, info.nFileIndexLow); } + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "O&:_isdir", + PyUnicode_FSConverter, &opath)) + return NULL; + + path = PyBytes_AsString(opath); + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ PyDoc_STRVAR(posix_mkdir__doc__, @@ -9561,6 +9597,7 @@ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, NULL}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 02:30:37 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 02:30:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Merge?= Message-ID: http://hg.python.org/cpython/rev/f1509fc75435 changeset: 70715:f1509fc75435 branch: 2.7 parent: 70661:6e7a98cfcfab user: Brian Curtin date: Wed Jun 08 19:29:53 2011 -0500 summary: Merge files: Lib/ntpath.py | 12 ++++++++++ Misc/NEWS | 3 ++ Modules/posixmodule.c | 36 +++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 0 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -521,3 +521,15 @@ if not rel_list: return curdir return join(*rel_list) + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir +except ImportError: + from genericpath import isdir as _isdir + +def isdir(path): + return _isdir(path) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Library ------- +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Issue #12080: Fix a performance issue in Decimal._power_exact that caused some corner-case Decimal.__pow__ calls to take an unreasonably long time. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4199,6 +4199,41 @@ CloseHandle(handle); return result; } + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "et:_isdir", + Py_FileSystemDefaultEncoding, &path)) + return NULL; + + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ #ifdef HAVE_PLOCK @@ -8968,6 +9003,7 @@ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, NULL}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Thu Jun 9 05:09:40 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 09 Jun 2011 05:09:40 +0200 Subject: [Python-checkins] Daily reference leaks (567f30527913): sum=399 Message-ID: results for 567f30527913 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogCZnMwA', '-x'] From python-checkins at python.org Thu Jun 9 13:16:30 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 13:16:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Add_examples_th?= =?utf8?q?at_work_on_Windows_to_distutils_docs_=28=231626300=29?= Message-ID: http://hg.python.org/cpython/rev/2951641faed1 changeset: 70716:2951641faed1 branch: 2.7 parent: 70661:6e7a98cfcfab user: ?ric Araujo date: Wed Jun 08 01:11:36 2011 +0200 summary: Add examples that work on Windows to distutils docs (#1626300) files: Doc/distutils/introduction.rst | 10 ++++++++-- Doc/install/index.rst | 15 +++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 13:16:31 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 13:16:31 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/fd477fe2da05 changeset: 70717:fd477fe2da05 branch: 2.7 parent: 70715:f1509fc75435 parent: 70716:2951641faed1 user: ?ric Araujo date: Thu Jun 09 13:14:12 2011 +0200 summary: Branch merge files: Doc/distutils/introduction.rst | 10 ++++++++-- Doc/install/index.rst | 15 +++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:10:56 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:10:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging_cleanup=3A_remove?= =?utf8?q?_use_of_script=5Fname_where_obsolete?= Message-ID: http://hg.python.org/cpython/rev/6bfd252c7cc3 changeset: 70718:6bfd252c7cc3 parent: 70709:5392be94ea65 user: ?ric Araujo date: Wed Jun 08 04:06:50 2011 +0200 summary: Packaging cleanup: remove use of script_name where obsolete files: Lib/packaging/run.py | 1 - Lib/packaging/tests/test_command_bdist_dumb.py | 1 - Lib/packaging/tests/test_command_build_py.py | 4 ---- Lib/packaging/tests/test_command_install_dist.py | 2 -- Lib/packaging/tests/test_command_install_lib.py | 2 -- Lib/packaging/tests/test_command_sdist.py | 10 ---------- 6 files changed, 0 insertions(+), 20 deletions(-) diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -405,7 +405,6 @@ self.verbose = 1 self.dry_run = False self.help = False - self.script_name = 'pysetup' self.cmdclass = {} self.commands = [] self.command_options = {} diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -49,7 +49,6 @@ 'py_modules': ['foo'], 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'}) - dist.script_name = 'setup.py' os.chdir(pkg_dir) sys.argv[:] = ['setup.py'] diff --git a/Lib/packaging/tests/test_command_build_py.py b/Lib/packaging/tests/test_command_build_py.py --- a/Lib/packaging/tests/test_command_build_py.py +++ b/Lib/packaging/tests/test_command_build_py.py @@ -33,9 +33,7 @@ dist = Distribution({"packages": ["pkg"], "package_dir": sources}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") dist.command_obj["build"] = support.DummyCommand( force=False, build_lib=destination, @@ -89,8 +87,6 @@ dist = Distribution({"packages": ["pkg"], "package_dir": sources, "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") dist.script_args = ["build"] dist.parse_command_line() diff --git a/Lib/packaging/tests/test_command_install_dist.py b/Lib/packaging/tests/test_command_install_dist.py --- a/Lib/packaging/tests/test_command_install_dist.py +++ b/Lib/packaging/tests/test_command_install_dist.py @@ -30,8 +30,6 @@ destination = os.path.join(builddir, "installation") dist = Distribution({"name": "foopkg"}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(builddir, "setup.py") dist.command_obj["build"] = support.DummyCommand( build_base=builddir, build_lib=os.path.join(builddir, "lib"), diff --git a/Lib/packaging/tests/test_command_install_lib.py b/Lib/packaging/tests/test_command_install_lib.py --- a/Lib/packaging/tests/test_command_install_lib.py +++ b/Lib/packaging/tests/test_command_install_lib.py @@ -65,7 +65,6 @@ self.write_file(f, '# python package') cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] cmd.distribution.packages = [pkg_dir] - cmd.distribution.script_name = 'setup.py' # make sure the build_lib is set the temp dir build_dir = os.path.split(pkg_dir)[0] @@ -86,7 +85,6 @@ self.write_file(f, '# python package') cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] cmd.distribution.packages = [pkg_dir] - cmd.distribution.script_name = 'setup.py' # get_input should return 2 elements self.assertEqual(len(cmd.get_inputs()), 2) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -24,12 +24,6 @@ from packaging.tests import support from shutil import get_archive_formats -SETUP_PY = """ -from packaging.core import setup -import somecode - -setup(name='fake') -""" MANIFEST = """\ # file GENERATED by packaging, do NOT edit @@ -57,8 +51,6 @@ restore_environ = ['HOME'] def setUp(self): - # PyPIRCCommandTestCase creates a temp dir already - # and put it in self.tmp_dir super(SDistTestCase, self).setUp() self.tmp_dir = self.mkdtemp() os.environ['HOME'] = self.tmp_dir @@ -69,7 +61,6 @@ # a package, and a README self.write_file((self.tmp_dir, 'README'), 'xxx') self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#') - self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY) os.chdir(self.tmp_dir) def tearDown(self): @@ -84,7 +75,6 @@ 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'} dist = Distribution(metadata) - dist.script_name = 'setup.py' dist.packages = ['somecode'] dist.include_package_data = True cmd = sdist(dist) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:10:57 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:10:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging_cleanup=3A_normal?= =?utf8?q?ize_print_calls=2E?= Message-ID: http://hg.python.org/cpython/rev/743b367debf1 changeset: 70719:743b367debf1 user: ?ric Araujo date: Wed Jun 08 04:10:57 2011 +0200 summary: Packaging cleanup: normalize print calls. Namely: use default arguments instead of explicit empty string; use multiple arguments instead of building strings. files: Lib/packaging/depgraph.py | 6 ++++-- Lib/packaging/dist.py | 8 ++++---- Lib/packaging/run.py | 20 ++++++++++---------- Lib/packaging/util.py | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Lib/packaging/depgraph.py b/Lib/packaging/depgraph.py --- a/Lib/packaging/depgraph.py +++ b/Lib/packaging/depgraph.py @@ -236,7 +236,9 @@ except Exception as e: tempout.seek(0) tempout = tempout.read() - print('Could not generate the graph\n%s\n%s\n' % (tempout, e)) + print('Could not generate the graph') + print(tempout) + print(e) sys.exit(1) for dist, reqs in graph.missing.items(): @@ -246,7 +248,7 @@ # XXX replace with argparse if len(sys.argv) == 1: print('Dependency graph:') - print(' ' + repr(graph).replace('\n', '\n ')) + print(' ', repr(graph).replace('\n', '\n ')) sys.exit(0) elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'): if len(sys.argv) > 2: diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -509,14 +509,14 @@ options = self.global_options parser.set_option_table(options) parser.print_help(self.common_usage + "\nGlobal options:") - print('') + print() if display_options: parser.set_option_table(self.display_options) parser.print_help( "Information display options (just display " + "information, ignore any commands)") - print('') + print() for command in self.commands: if isinstance(command, type) and issubclass(command, Command): @@ -529,7 +529,7 @@ else: parser.set_option_table(cls.user_options) parser.print_help("Options for %r command:" % cls.__name__) - print('') + print() print(gen_usage(self.script_name)) @@ -544,7 +544,7 @@ # we ignore "foo bar"). if self.help_commands: self.print_commands() - print('') + print() print(gen_usage(self.script_name)) return 1 diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -286,9 +286,9 @@ value = metadata[key] if isinstance(value, list): for v in value: - print(' ' + v) + print(' ', v) else: - print(' ' + value.replace('\n', '\n ')) + print(' ', value.replace('\n', '\n ')) @action_help(remove_usage) @@ -366,7 +366,7 @@ print('%s %s at %s' % (dist.name, dist.metadata['version'], dist.path)) number += 1 - print('') + print() if number == 0: print('Nothing seems to be installed.') else: @@ -573,17 +573,17 @@ from packaging.command.cmd import Command print('Usage: pysetup [options] action [action_options]') - print('') + print() if global_options_: self.print_usage(self.parser) - print('') + print() if display_options_: parser.set_option_table(display_options) parser.print_help( "Information display options (just display " + "information, ignore any commands)") - print('') + print() for command in commands: if isinstance(command, type) and issubclass(command, Command): @@ -597,15 +597,15 @@ parser.set_option_table(cls.user_options) parser.print_help("Options for %r command:" % cls.__name__) - print('') + print() def _show_command_help(self, command): if isinstance(command, str): command = get_command_class(command) desc = getattr(command, 'description', '(no description available)') - print('Description: %s' % desc) - print('') + print('Description:', desc) + print() if (hasattr(command, 'help_options') and isinstance(command.help_options, list)): @@ -615,7 +615,7 @@ self.parser.set_option_table(command.user_options) self.parser.print_help("Options:") - print('') + print() def _get_command_groups(self): """Helper function to retrieve all the command class names divided diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1099,7 +1099,7 @@ response = input(message) response = response.strip().lower() if response not in options: - print('invalid response: %r' % response) + print('invalid response:', repr(response)) print('choose one of', ', '.join(repr(o) for o in options)) else: return response -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:10:57 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:10:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_misunderstanding_of_how?= =?utf8?q?_booleans_work?= Message-ID: http://hg.python.org/cpython/rev/164158e8207e changeset: 70720:164158e8207e user: ?ric Araujo date: Wed Jun 08 04:31:18 2011 +0200 summary: Fix misunderstanding of how booleans work files: Lib/packaging/pypi/simple.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -231,7 +231,8 @@ """ self._mirrors_used.add(self.index_url) index_url = self._mirrors.pop() - if not ("http://" or "https://" or "file://") in index_url: + # XXX use urllib.parse for a real check of missing scheme part + if not index_url.startswith(("http://", "https://", "file://")): index_url = "http://%s" % index_url if not index_url.endswith("/simple"): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:10:58 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:10:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Remove_outdated?= =?utf8?q?_bit_of_advice_=28584f9c213a6d_follow-up=29?= Message-ID: http://hg.python.org/cpython/rev/096d5e8a1a4c changeset: 70721:096d5e8a1a4c branch: 3.2 parent: 70700:0aa3064d1cef user: ?ric Araujo date: Wed Jun 08 00:47:49 2011 +0200 summary: Remove outdated bit of advice (584f9c213a6d follow-up) files: Doc/documenting/markup.rst | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:10:59 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:10:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Add_examples_th?= =?utf8?q?at_work_on_Windows_to_distutils_docs_=28=231626300=29?= Message-ID: http://hg.python.org/cpython/rev/072dbebaa83b changeset: 70722:072dbebaa83b branch: 3.2 user: ?ric Araujo date: Wed Jun 08 01:11:36 2011 +0200 summary: Add examples that work on Windows to distutils docs (#1626300) files: Doc/distutils/introduction.rst | 10 ++++++++-- Doc/install/index.rst | 15 +++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:00 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Add_links_from_?= =?utf8?q?builtins_module_docs_to_built-in_functions_and_constants_docs?= Message-ID: http://hg.python.org/cpython/rev/69b416cd1727 changeset: 70723:69b416cd1727 branch: 3.2 user: ?ric Araujo date: Wed Jun 08 04:53:20 2011 +0200 summary: Add links from builtins module docs to built-in functions and constants docs files: Doc/library/builtins.rst | 4 +++- Doc/library/constants.rst | 2 ++ 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,7 +7,9 @@ This module provides direct access to all 'built-in' identifiers of Python; for example, ``builtins.open`` is the full name for the built-in function -:func:`open`. +:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for +documentation. + This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -1,3 +1,5 @@ +.. _built-in-consts: + Built-in Constants ================== -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:00 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging=3A_always_use_rep?= =?utf8?q?r_to_display_project_names=2E?= Message-ID: http://hg.python.org/cpython/rev/3ebabfbf6fe3 changeset: 70724:3ebabfbf6fe3 parent: 70720:164158e8207e user: ?ric Araujo date: Wed Jun 08 04:40:13 2011 +0200 summary: Packaging: always use repr to display project names. This helps debugging in case of trailing blanks and such things. files: Lib/packaging/depgraph.py | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Lib/packaging/depgraph.py b/Lib/packaging/depgraph.py --- a/Lib/packaging/depgraph.py +++ b/Lib/packaging/depgraph.py @@ -72,7 +72,7 @@ self.missing[distribution].append(requirement) def _repr_dist(self, dist): - return '%s %s' % (dist.name, dist.metadata['Version']) + return '%r %s' % (dist.name, dist.metadata['Version']) def repr_node(self, dist, level=1): """Prints only a subgraph""" @@ -154,8 +154,8 @@ if len(comps) == 2: version = comps[1] if len(version) < 3 or version[0] != '(' or version[-1] != ')': - raise PackagingError('Distribution %s has ill formed' \ - 'provides field: %s' % (dist.name, p)) + raise PackagingError('distribution %r has ill-formed' + 'provides field: %r' % (dist.name, p)) version = version[1:-1] # trim off parenthesis if not name in provided: provided[name] = [] @@ -204,8 +204,9 @@ :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested """ - if not dist in dists: - raise ValueError('The given distribution is not a member of the list') + if dist not in dists: + raise ValueError('given distribution %r is not a member of the list' % + dist.name) graph = generate_graph(dists) dep = [dist] # dependent distributions @@ -243,7 +244,7 @@ for dist, reqs in graph.missing.items(): if len(reqs) > 0: - print("Warning: Missing dependencies for %s:" % dist.name, + print("Warning: Missing dependencies for %r:" % dist.name, ", ".join(reqs)) # XXX replace with argparse if len(sys.argv) == 1: @@ -261,7 +262,7 @@ tempout.seek(0) tempout = tempout.read() print(tempout) - print('Dot file written at "%s"' % filename) + print('Dot file written at %r' % filename) sys.exit(0) else: print('Supported option: -d [filename]') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:01 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Style_change_in_packaging?= =?utf8?b?OiB1c2Ug4oCcbm90IGlu4oCdIG92ZXIg4oCcbm90IHggaW7igJ0u?= Message-ID: http://hg.python.org/cpython/rev/79f7ad26829e changeset: 70725:79f7ad26829e user: ?ric Araujo date: Wed Jun 08 04:47:13 2011 +0200 summary: Style change in packaging: use ?not in? over ?not x in?. Such tests are IMO easier to read if both operators are grouped. files: Lib/packaging/create.py | 8 ++++---- Lib/packaging/database.py | 6 +++--- Lib/packaging/depgraph.py | 8 ++++---- Lib/packaging/pypi/dist.py | 6 +++--- Lib/packaging/pypi/simple.py | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -175,11 +175,11 @@ def _build_classifiers_dict(classifiers): d = {} for key in classifiers: - subDict = d + subdict = d for subkey in key.split(' :: '): - if not subkey in subDict: - subDict[subkey] = {} - subDict = subDict[subkey] + if subkey not in subdict: + subdict[subkey] = {} + subdict = subdict[subkey] return d CLASSIFIERS = _build_classifiers_dict(_CLASSIFIERS_LIST) diff --git a/Lib/packaging/database.py b/Lib/packaging/database.py --- a/Lib/packaging/database.py +++ b/Lib/packaging/database.py @@ -104,12 +104,12 @@ for dist in _yield_distributions(gen_dist, gen_egg, paths): if isinstance(dist, Distribution): _cache_path[dist.path] = dist - if not dist.name in _cache_name: + if dist.name not in _cache_name: _cache_name[dist.name] = [] _cache_name[dist.name].append(dist) else: _cache_path_egg[dist.path] = dist - if not dist.name in _cache_name_egg: + if dist.name not in _cache_name_egg: _cache_name_egg[dist.name] = [] _cache_name_egg[dist.name].append(dist) @@ -150,7 +150,7 @@ self.version = self.metadata['Version'] self.path = path - if _cache_enabled and not path in _cache_path: + if _cache_enabled and path not in _cache_path: _cache_path[path] = self def __repr__(self): diff --git a/Lib/packaging/depgraph.py b/Lib/packaging/depgraph.py --- a/Lib/packaging/depgraph.py +++ b/Lib/packaging/depgraph.py @@ -58,7 +58,7 @@ """ self.adjacency_list[x].append((y, label)) # multiple edges are allowed, so be careful - if not x in self.reverse_list[y]: + if x not in self.reverse_list[y]: self.reverse_list[y].append(x) def add_missing(self, distribution, requirement): @@ -157,7 +157,7 @@ raise PackagingError('distribution %r has ill-formed' 'provides field: %r' % (dist.name, p)) version = version[1:-1] # trim off parenthesis - if not name in provided: + if name not in provided: provided[name] = [] provided[name].append((version, dist)) @@ -174,7 +174,7 @@ name = predicate.name - if not name in provided: + if name not in provided: graph.add_missing(dist, req) else: matched = False @@ -216,7 +216,7 @@ node = fringe.pop() dep.append(node) for prev in graph.reverse_list[node]: - if not prev in dep: + if prev not in dep: fringe.append(prev) dep.pop(0) # remove dist from dep, was there to prevent infinite loops diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -256,7 +256,7 @@ hashlib.new(hashname) except ValueError: raise UnsupportedHashName(hashname) - if not url in [u['url'] for u in self.urls]: + if url not in [u['url'] for u in self.urls]: self.urls.append({ 'url': url, 'hashname': hashname, @@ -329,7 +329,7 @@ url param""" hashname = self.url['hashname'] expected_hashval = self.url['hashval'] - if not None in (expected_hashval, hashname): + if None not in (expected_hashval, hashname): with open(filename, 'rb') as f: hashval = hashlib.new(hashname) hashval.update(f.read()) @@ -409,7 +409,7 @@ (release.name, self.name)) version = str(release.version) - if not version in self.get_versions(): + if version not in self.get_versions(): # append only if not already exists self.releases.append(release) for dist in release.dists.values(): diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -283,7 +283,7 @@ name = release.name else: name = release_info['name'] - if not name.lower() in self._projects: + if name.lower() not in self._projects: self._projects[name.lower()] = ReleasesList(name, index=self._index) if release: @@ -321,7 +321,7 @@ # it's a distribution, so create a dist object try: infos = get_infos_from_url(link, project_name, - is_external=not self.index_url in url) + is_external=self.index_url not in url) except CantParseArchiveName as e: if self.verbose: logger.warning( -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:02 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_example_in_packaging_te?= =?utf8?q?st=5Fconfig=2E?= Message-ID: http://hg.python.org/cpython/rev/24912715571f changeset: 70726:24912715571f user: ?ric Araujo date: Thu Jun 09 07:47:25 2011 +0200 summary: Fix example in packaging test_config. The example C extension used the ?three.fast_taunt? name, but no ?three? parent was defined in the setup.cfg. This did not cause a failure nor even print a warning, we may want to change that. files: Lib/packaging/tests/test_config.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -114,7 +114,7 @@ GecodeInt GecodeKernel -- sys.platform == 'win32' [extension=fast_taunt] -name = three.fast_taunt +name = two.fast_taunt sources = cxx_src/utils_taunt.cxx cxx_src/python_module.cxx include_dirs = /usr/include/gecode @@ -305,7 +305,7 @@ self.assertEqual(ext.extra_link_args, ['`gcc -print-file-name=libgcc.a`', '-shared']) - ext = ext_modules.get('three.fast_taunt') + ext = ext_modules.get('two.fast_taunt') self.assertEqual(ext.sources, ['cxx_src/utils_taunt.cxx', 'cxx_src/python_module.cxx']) self.assertEqual(ext.include_dirs, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:03 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_incorrect_nesting_of_se?= =?utf8?q?ctions_in_setup=2Ecfg_specification?= Message-ID: http://hg.python.org/cpython/rev/a4a9325f267f changeset: 70727:a4a9325f267f user: ?ric Araujo date: Thu Jun 09 08:15:47 2011 +0200 summary: Fix incorrect nesting of sections in setup.cfg specification files: Doc/packaging/setupcfg.rst | 35 +++++++++++++------------ 1 files changed, 18 insertions(+), 17 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -147,7 +147,7 @@ Global options -============== +-------------- Contains global options for Packaging. This section is shared with Distutils. @@ -185,7 +185,7 @@ Metadata -======== +-------- The metadata section contains the metadata for the project as described in :PEP:`345`. Field names are case-insensitive. @@ -308,7 +308,7 @@ Files -===== +----- This section describes the files included in the project. @@ -352,7 +352,7 @@ Resources ---------- +^^^^^^^^^ This section describes the files used by the project which must not be installed in the same place that python modules or libraries, they are called @@ -448,10 +448,10 @@ More control on source part -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""""""" Glob syntax -""""""""""" +''''''''''' When you declare source file, you can use a glob-like syntax to match multiples file, for example:: @@ -469,7 +469,7 @@ .. TODO Add examples Order of declaration -"""""""""""""""""""" +'''''''''''''''''''' The order of declaration is important if one file match multiple rules. The last rules matched by file is used, this is useful if you have this source tree:: @@ -492,7 +492,7 @@ doc/README = {help} Exclude -""""""" +''''''' You can exclude some files of resources declaration by giving no destination, it can be useful if you have a non-resources file in the same directory of @@ -513,12 +513,12 @@ doc/RELEASES = More control on destination part -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""" .. _setupcfg-resources-base-prefix: Defining a base prefix -"""""""""""""""""""""" +'''''''''''''''''''''' When you define your resources, you can have more control of how the final path is computed. @@ -577,7 +577,7 @@ Overwriting paths for categories -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""" This part is intended for system administrators or downstream OS packagers. @@ -614,18 +614,18 @@ Defining extra categories -^^^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""""" .. TODO Examples -^^^^^^^^ +"""""""" These examples are incremental but work unitarily. Resources in root dir -""""""""""""""""""""" +''''''''''''''''''''' Source tree:: @@ -647,7 +647,7 @@ Now let's move all the scripts into a scripts directory. Resources in sub-directory -"""""""""""""""""""""""""" +'''''''''''''''''''''''''' Source tree:: @@ -673,7 +673,7 @@ Now let's add some docs. Resources in multiple sub-directories -""""""""""""""""""""""""""""""""""""" +''''''''''''''''''''''''''''''''''''' Source tree:: @@ -706,7 +706,7 @@ Now let's add some scripts for windows users. Complete example -"""""""""""""""" +'''''''''''''''' Source tree:: @@ -737,7 +737,7 @@ Command sections -================ +---------------- To pass options to commands without having to type them on the command line for each invocation, you can write them in the :file:`setup.cfg` file, in a -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:03 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Document_how_to_define_exte?= =?utf8?q?nsion_modules_in_setup=2Ecfg?= Message-ID: http://hg.python.org/cpython/rev/068cd59b2213 changeset: 70728:068cd59b2213 user: ?ric Araujo date: Thu Jun 09 08:18:17 2011 +0200 summary: Document how to define extension modules in setup.cfg files: Doc/library/packaging.compiler.rst | 6 ++- Doc/packaging/setupcfg.rst | 32 ++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Doc/library/packaging.compiler.rst b/Doc/library/packaging.compiler.rst --- a/Doc/library/packaging.compiler.rst +++ b/Doc/library/packaging.compiler.rst @@ -569,10 +569,10 @@ .. class:: Extension The Extension class describes a single C or C++ extension module. It accepts - the following keyword arguments in its constructor + the following keyword arguments in its constructor: +------------------------+--------------------------------+---------------------------+ - | argument name | value | type | + | argument name | value | type [#]_ | +========================+================================+===========================+ | *name* | the full name of the | string | | | extension, including any | | @@ -670,3 +670,5 @@ | | from the source extensions if | | | | not provided. | | +------------------------+--------------------------------+---------------------------+ + +.. [#] For values documented as lists, the given type is the type of each element. diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -141,6 +141,9 @@ Modules, scripts, data, documentation and other files to include in the distribution. +extension sections + Options used to build extension modules. + command sections Options given for specific commands, identical to those that can be given on the command line. @@ -736,6 +739,35 @@ {scripts} category. +Extension sections +------------------ + +If a project includes extension modules written in C or C++, each one of them +needs to have its options defined in a dedicated section. Here's an example:: + + [files] + packages = coconut + + [extension=_fastcoconut] + name = coconut._fastcoconut + language = cxx + sources = cxx_src/cononut_utils.cxx + cxx_src/python_module.cxx + include_dirs = /usr/include/gecode + /usr/include/blitz + extra_compile_args = + -fPIC -O2 + -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32' + /DGECODE_VERSION='win32' -- sys.platform == 'win32' + +The section name must start with ``extension=``; the righ-hand part is currently +discarded. Valid fields and their values are listed in the documentation of the +:class:`packaging.compiler.extension.Extension` class; values documented as +Python lists translate to multi-line values in the configuration file. In +addition, multi-line values accept environment markers on each line, after a +``--``. + + Command sections ---------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:04 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_a_few_misus?= =?utf8?q?es_of_=3Aoption=3A_I_missed_in_r86521=2E?= Message-ID: http://hg.python.org/cpython/rev/59d785ea0039 changeset: 70729:59d785ea0039 branch: 3.2 parent: 70723:69b416cd1727 user: ?ric Araujo date: Wed Jun 08 05:29:39 2011 +0200 summary: Fix a few misuses of :option: I missed in r86521. Extract of the commit message: Fix usage of :option: in the docs (#9312). :option: is used to create a link to an option of python, not to mark up any instance of any arbitrary command-line option. These were changed to ````. files: Doc/c-api/intro.rst | 4 ++-- Doc/license.rst | 4 ++-- Doc/using/cmdline.rst | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -588,8 +588,8 @@ Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -845,7 +845,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -874,7 +874,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -501,7 +501,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:05 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:05 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/42cd9776017d changeset: 70730:42cd9776017d branch: 3.2 parent: 70713:88e318166eaf parent: 70729:59d785ea0039 user: ?ric Araujo date: Thu Jun 09 13:13:24 2011 +0200 summary: Branch merge files: Doc/c-api/intro.rst | 4 ++-- Doc/distutils/introduction.rst | 10 ++++++++-- Doc/documenting/markup.rst | 11 ++++++----- Doc/install/index.rst | 15 +++++++++------ Doc/library/builtins.rst | 4 +++- Doc/library/constants.rst | 2 ++ Doc/license.rst | 4 ++-- Doc/using/cmdline.rst | 2 +- 8 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -588,8 +588,8 @@ Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,7 +7,9 @@ This module provides direct access to all 'built-in' identifiers of Python; for example, ``builtins.open`` is the full name for the built-in function -:func:`open`. +:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for +documentation. + This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -1,3 +1,5 @@ +.. _built-in-consts: + Built-in Constants ================== diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -845,7 +845,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -874,7 +874,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -501,7 +501,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:05 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Stop_creating_a_Python-X=2E?= =?utf8?q?Y=2EZ-pyX=2EY=2Eegg-info_file_on_install_=28=2310645=29?= Message-ID: http://hg.python.org/cpython/rev/e3f6c10eb590 changeset: 70731:e3f6c10eb590 parent: 70728:068cd59b2213 user: ?ric Araujo date: Thu Jun 09 14:07:02 2011 +0200 summary: Stop creating a Python-X.Y.Z-pyX.Y.egg-info file on install (#10645) files: setup.py | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1780,6 +1780,13 @@ install.initialize_options(self) self.warn_dir=0 + # Customize subcommands to not install an egg-info file for Python + sub_commands = [('install_lib', install.has_lib), + ('install_headers', install.has_headers), + ('install_scripts', install.has_scripts), + ('install_data', install.has_data)] + + class PyBuildInstallLib(install_lib): # Do exactly what install_lib does but make sure correct access modes get # set on installed directories and files. All installed files with get -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:06 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/bffb4f09f080 changeset: 70732:bffb4f09f080 parent: 70714:567f30527913 parent: 70731:e3f6c10eb590 user: ?ric Araujo date: Thu Jun 09 14:07:46 2011 +0200 summary: Branch merge files: Doc/library/packaging.compiler.rst | 6 +- Doc/packaging/setupcfg.rst | 67 +++++++-- Lib/packaging/create.py | 8 +- Lib/packaging/database.py | 6 +- Lib/packaging/depgraph.py | 29 ++- Lib/packaging/dist.py | 8 +- Lib/packaging/pypi/dist.py | 6 +- Lib/packaging/pypi/simple.py | 7 +- Lib/packaging/run.py | 21 +- Lib/packaging/tests/test_command_bdist_dumb.py | 1 - Lib/packaging/tests/test_command_build_py.py | 4 - Lib/packaging/tests/test_command_install_dist.py | 2 - Lib/packaging/tests/test_command_install_lib.py | 2 - Lib/packaging/tests/test_command_sdist.py | 10 - Lib/packaging/tests/test_config.py | 4 +- Lib/packaging/util.py | 2 +- setup.py | 7 + 17 files changed, 108 insertions(+), 82 deletions(-) diff --git a/Doc/library/packaging.compiler.rst b/Doc/library/packaging.compiler.rst --- a/Doc/library/packaging.compiler.rst +++ b/Doc/library/packaging.compiler.rst @@ -569,10 +569,10 @@ .. class:: Extension The Extension class describes a single C or C++ extension module. It accepts - the following keyword arguments in its constructor + the following keyword arguments in its constructor: +------------------------+--------------------------------+---------------------------+ - | argument name | value | type | + | argument name | value | type [#]_ | +========================+================================+===========================+ | *name* | the full name of the | string | | | extension, including any | | @@ -670,3 +670,5 @@ | | from the source extensions if | | | | not provided. | | +------------------------+--------------------------------+---------------------------+ + +.. [#] For values documented as lists, the given type is the type of each element. diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -141,13 +141,16 @@ Modules, scripts, data, documentation and other files to include in the distribution. +extension sections + Options used to build extension modules. + command sections Options given for specific commands, identical to those that can be given on the command line. Global options -============== +-------------- Contains global options for Packaging. This section is shared with Distutils. @@ -185,7 +188,7 @@ Metadata -======== +-------- The metadata section contains the metadata for the project as described in :PEP:`345`. Field names are case-insensitive. @@ -308,7 +311,7 @@ Files -===== +----- This section describes the files included in the project. @@ -352,7 +355,7 @@ Resources ---------- +^^^^^^^^^ This section describes the files used by the project which must not be installed in the same place that python modules or libraries, they are called @@ -448,10 +451,10 @@ More control on source part -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""""""" Glob syntax -""""""""""" +''''''''''' When you declare source file, you can use a glob-like syntax to match multiples file, for example:: @@ -469,7 +472,7 @@ .. TODO Add examples Order of declaration -"""""""""""""""""""" +'''''''''''''''''''' The order of declaration is important if one file match multiple rules. The last rules matched by file is used, this is useful if you have this source tree:: @@ -492,7 +495,7 @@ doc/README = {help} Exclude -""""""" +''''''' You can exclude some files of resources declaration by giving no destination, it can be useful if you have a non-resources file in the same directory of @@ -513,12 +516,12 @@ doc/RELEASES = More control on destination part -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""" .. _setupcfg-resources-base-prefix: Defining a base prefix -"""""""""""""""""""""" +'''''''''''''''''''''' When you define your resources, you can have more control of how the final path is computed. @@ -577,7 +580,7 @@ Overwriting paths for categories -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""" This part is intended for system administrators or downstream OS packagers. @@ -614,18 +617,18 @@ Defining extra categories -^^^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""""" .. TODO Examples -^^^^^^^^ +"""""""" These examples are incremental but work unitarily. Resources in root dir -""""""""""""""""""""" +''''''''''''''''''''' Source tree:: @@ -647,7 +650,7 @@ Now let's move all the scripts into a scripts directory. Resources in sub-directory -"""""""""""""""""""""""""" +'''''''''''''''''''''''''' Source tree:: @@ -673,7 +676,7 @@ Now let's add some docs. Resources in multiple sub-directories -""""""""""""""""""""""""""""""""""""" +''''''''''''''''''''''''''''''''''''' Source tree:: @@ -706,7 +709,7 @@ Now let's add some scripts for windows users. Complete example -"""""""""""""""" +'''''''''''''''' Source tree:: @@ -736,8 +739,37 @@ {scripts} category. +Extension sections +------------------ + +If a project includes extension modules written in C or C++, each one of them +needs to have its options defined in a dedicated section. Here's an example:: + + [files] + packages = coconut + + [extension=_fastcoconut] + name = coconut._fastcoconut + language = cxx + sources = cxx_src/cononut_utils.cxx + cxx_src/python_module.cxx + include_dirs = /usr/include/gecode + /usr/include/blitz + extra_compile_args = + -fPIC -O2 + -DGECODE_VERSION=$(./gecode_version) -- sys.platform != 'win32' + /DGECODE_VERSION='win32' -- sys.platform == 'win32' + +The section name must start with ``extension=``; the righ-hand part is currently +discarded. Valid fields and their values are listed in the documentation of the +:class:`packaging.compiler.extension.Extension` class; values documented as +Python lists translate to multi-line values in the configuration file. In +addition, multi-line values accept environment markers on each line, after a +``--``. + + Command sections -================ +---------------- To pass options to commands without having to type them on the command line for each invocation, you can write them in the :file:`setup.cfg` file, in a diff --git a/Lib/packaging/create.py b/Lib/packaging/create.py --- a/Lib/packaging/create.py +++ b/Lib/packaging/create.py @@ -175,11 +175,11 @@ def _build_classifiers_dict(classifiers): d = {} for key in classifiers: - subDict = d + subdict = d for subkey in key.split(' :: '): - if not subkey in subDict: - subDict[subkey] = {} - subDict = subDict[subkey] + if subkey not in subdict: + subdict[subkey] = {} + subdict = subdict[subkey] return d CLASSIFIERS = _build_classifiers_dict(_CLASSIFIERS_LIST) diff --git a/Lib/packaging/database.py b/Lib/packaging/database.py --- a/Lib/packaging/database.py +++ b/Lib/packaging/database.py @@ -104,12 +104,12 @@ for dist in _yield_distributions(gen_dist, gen_egg, paths): if isinstance(dist, Distribution): _cache_path[dist.path] = dist - if not dist.name in _cache_name: + if dist.name not in _cache_name: _cache_name[dist.name] = [] _cache_name[dist.name].append(dist) else: _cache_path_egg[dist.path] = dist - if not dist.name in _cache_name_egg: + if dist.name not in _cache_name_egg: _cache_name_egg[dist.name] = [] _cache_name_egg[dist.name].append(dist) @@ -150,7 +150,7 @@ self.version = self.metadata['Version'] self.path = path - if _cache_enabled and not path in _cache_path: + if _cache_enabled and path not in _cache_path: _cache_path[path] = self def __repr__(self): diff --git a/Lib/packaging/depgraph.py b/Lib/packaging/depgraph.py --- a/Lib/packaging/depgraph.py +++ b/Lib/packaging/depgraph.py @@ -58,7 +58,7 @@ """ self.adjacency_list[x].append((y, label)) # multiple edges are allowed, so be careful - if not x in self.reverse_list[y]: + if x not in self.reverse_list[y]: self.reverse_list[y].append(x) def add_missing(self, distribution, requirement): @@ -72,7 +72,7 @@ self.missing[distribution].append(requirement) def _repr_dist(self, dist): - return '%s %s' % (dist.name, dist.metadata['Version']) + return '%r %s' % (dist.name, dist.metadata['Version']) def repr_node(self, dist, level=1): """Prints only a subgraph""" @@ -154,10 +154,10 @@ if len(comps) == 2: version = comps[1] if len(version) < 3 or version[0] != '(' or version[-1] != ')': - raise PackagingError('Distribution %s has ill formed' \ - 'provides field: %s' % (dist.name, p)) + raise PackagingError('distribution %r has ill-formed' + 'provides field: %r' % (dist.name, p)) version = version[1:-1] # trim off parenthesis - if not name in provided: + if name not in provided: provided[name] = [] provided[name].append((version, dist)) @@ -174,7 +174,7 @@ name = predicate.name - if not name in provided: + if name not in provided: graph.add_missing(dist, req) else: matched = False @@ -204,8 +204,9 @@ :param dists: a list of distributions :param dist: a distribution, member of *dists* for which we are interested """ - if not dist in dists: - raise ValueError('The given distribution is not a member of the list') + if dist not in dists: + raise ValueError('given distribution %r is not a member of the list' % + dist.name) graph = generate_graph(dists) dep = [dist] # dependent distributions @@ -215,7 +216,7 @@ node = fringe.pop() dep.append(node) for prev in graph.reverse_list[node]: - if not prev in dep: + if prev not in dep: fringe.append(prev) dep.pop(0) # remove dist from dep, was there to prevent infinite loops @@ -236,17 +237,19 @@ except Exception as e: tempout.seek(0) tempout = tempout.read() - print('Could not generate the graph\n%s\n%s\n' % (tempout, e)) + print('Could not generate the graph') + print(tempout) + print(e) sys.exit(1) for dist, reqs in graph.missing.items(): if len(reqs) > 0: - print("Warning: Missing dependencies for %s:" % dist.name, + print("Warning: Missing dependencies for %r:" % dist.name, ", ".join(reqs)) # XXX replace with argparse if len(sys.argv) == 1: print('Dependency graph:') - print(' ' + repr(graph).replace('\n', '\n ')) + print(' ', repr(graph).replace('\n', '\n ')) sys.exit(0) elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'): if len(sys.argv) > 2: @@ -259,7 +262,7 @@ tempout.seek(0) tempout = tempout.read() print(tempout) - print('Dot file written at "%s"' % filename) + print('Dot file written at %r' % filename) sys.exit(0) else: print('Supported option: -d [filename]') diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -509,14 +509,14 @@ options = self.global_options parser.set_option_table(options) parser.print_help(self.common_usage + "\nGlobal options:") - print('') + print() if display_options: parser.set_option_table(self.display_options) parser.print_help( "Information display options (just display " + "information, ignore any commands)") - print('') + print() for command in self.commands: if isinstance(command, type) and issubclass(command, Command): @@ -529,7 +529,7 @@ else: parser.set_option_table(cls.user_options) parser.print_help("Options for %r command:" % cls.__name__) - print('') + print() print(gen_usage(self.script_name)) @@ -544,7 +544,7 @@ # we ignore "foo bar"). if self.help_commands: self.print_commands() - print('') + print() print(gen_usage(self.script_name)) return 1 diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -256,7 +256,7 @@ hashlib.new(hashname) except ValueError: raise UnsupportedHashName(hashname) - if not url in [u['url'] for u in self.urls]: + if url not in [u['url'] for u in self.urls]: self.urls.append({ 'url': url, 'hashname': hashname, @@ -329,7 +329,7 @@ url param""" hashname = self.url['hashname'] expected_hashval = self.url['hashval'] - if not None in (expected_hashval, hashname): + if None not in (expected_hashval, hashname): with open(filename, 'rb') as f: hashval = hashlib.new(hashname) hashval.update(f.read()) @@ -409,7 +409,7 @@ (release.name, self.name)) version = str(release.version) - if not version in self.get_versions(): + if version not in self.get_versions(): # append only if not already exists self.releases.append(release) for dist in release.dists.values(): diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -231,7 +231,8 @@ """ self._mirrors_used.add(self.index_url) index_url = self._mirrors.pop() - if not ("http://" or "https://" or "file://") in index_url: + # XXX use urllib.parse for a real check of missing scheme part + if not index_url.startswith(("http://", "https://", "file://")): index_url = "http://%s" % index_url if not index_url.endswith("/simple"): @@ -282,7 +283,7 @@ name = release.name else: name = release_info['name'] - if not name.lower() in self._projects: + if name.lower() not in self._projects: self._projects[name.lower()] = ReleasesList(name, index=self._index) if release: @@ -320,7 +321,7 @@ # it's a distribution, so create a dist object try: infos = get_infos_from_url(link, project_name, - is_external=not self.index_url in url) + is_external=self.index_url not in url) except CantParseArchiveName as e: if self.verbose: logger.warning( diff --git a/Lib/packaging/run.py b/Lib/packaging/run.py --- a/Lib/packaging/run.py +++ b/Lib/packaging/run.py @@ -286,9 +286,9 @@ value = metadata[key] if isinstance(value, list): for v in value: - print(' ' + v) + print(' ', v) else: - print(' ' + value.replace('\n', '\n ')) + print(' ', value.replace('\n', '\n ')) @action_help(remove_usage) @@ -366,7 +366,7 @@ print('%s %s at %s' % (dist.name, dist.metadata['version'], dist.path)) number += 1 - print('') + print() if number == 0: print('Nothing seems to be installed.') else: @@ -405,7 +405,6 @@ self.verbose = 1 self.dry_run = False self.help = False - self.script_name = 'pysetup' self.cmdclass = {} self.commands = [] self.command_options = {} @@ -574,17 +573,17 @@ from packaging.command.cmd import Command print('Usage: pysetup [options] action [action_options]') - print('') + print() if global_options_: self.print_usage(self.parser) - print('') + print() if display_options_: parser.set_option_table(display_options) parser.print_help( "Information display options (just display " + "information, ignore any commands)") - print('') + print() for command in commands: if isinstance(command, type) and issubclass(command, Command): @@ -598,15 +597,15 @@ parser.set_option_table(cls.user_options) parser.print_help("Options for %r command:" % cls.__name__) - print('') + print() def _show_command_help(self, command): if isinstance(command, str): command = get_command_class(command) desc = getattr(command, 'description', '(no description available)') - print('Description: %s' % desc) - print('') + print('Description:', desc) + print() if (hasattr(command, 'help_options') and isinstance(command.help_options, list)): @@ -616,7 +615,7 @@ self.parser.set_option_table(command.user_options) self.parser.print_help("Options:") - print('') + print() def _get_command_groups(self): """Helper function to retrieve all the command class names divided diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -49,7 +49,6 @@ 'py_modules': ['foo'], 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'}) - dist.script_name = 'setup.py' os.chdir(pkg_dir) sys.argv[:] = ['setup.py'] diff --git a/Lib/packaging/tests/test_command_build_py.py b/Lib/packaging/tests/test_command_build_py.py --- a/Lib/packaging/tests/test_command_build_py.py +++ b/Lib/packaging/tests/test_command_build_py.py @@ -33,9 +33,7 @@ dist = Distribution({"packages": ["pkg"], "package_dir": sources}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") dist.command_obj["build"] = support.DummyCommand( force=False, build_lib=destination, @@ -89,8 +87,6 @@ dist = Distribution({"packages": ["pkg"], "package_dir": sources, "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") dist.script_args = ["build"] dist.parse_command_line() diff --git a/Lib/packaging/tests/test_command_install_dist.py b/Lib/packaging/tests/test_command_install_dist.py --- a/Lib/packaging/tests/test_command_install_dist.py +++ b/Lib/packaging/tests/test_command_install_dist.py @@ -30,8 +30,6 @@ destination = os.path.join(builddir, "installation") dist = Distribution({"name": "foopkg"}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(builddir, "setup.py") dist.command_obj["build"] = support.DummyCommand( build_base=builddir, build_lib=os.path.join(builddir, "lib"), diff --git a/Lib/packaging/tests/test_command_install_lib.py b/Lib/packaging/tests/test_command_install_lib.py --- a/Lib/packaging/tests/test_command_install_lib.py +++ b/Lib/packaging/tests/test_command_install_lib.py @@ -65,7 +65,6 @@ self.write_file(f, '# python package') cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] cmd.distribution.packages = [pkg_dir] - cmd.distribution.script_name = 'setup.py' # make sure the build_lib is set the temp dir build_dir = os.path.split(pkg_dir)[0] @@ -86,7 +85,6 @@ self.write_file(f, '# python package') cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] cmd.distribution.packages = [pkg_dir] - cmd.distribution.script_name = 'setup.py' # get_input should return 2 elements self.assertEqual(len(cmd.get_inputs()), 2) diff --git a/Lib/packaging/tests/test_command_sdist.py b/Lib/packaging/tests/test_command_sdist.py --- a/Lib/packaging/tests/test_command_sdist.py +++ b/Lib/packaging/tests/test_command_sdist.py @@ -24,12 +24,6 @@ from packaging.tests import support from shutil import get_archive_formats -SETUP_PY = """ -from packaging.core import setup -import somecode - -setup(name='fake') -""" MANIFEST = """\ # file GENERATED by packaging, do NOT edit @@ -57,8 +51,6 @@ restore_environ = ['HOME'] def setUp(self): - # PyPIRCCommandTestCase creates a temp dir already - # and put it in self.tmp_dir super(SDistTestCase, self).setUp() self.tmp_dir = self.mkdtemp() os.environ['HOME'] = self.tmp_dir @@ -69,7 +61,6 @@ # a package, and a README self.write_file((self.tmp_dir, 'README'), 'xxx') self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#') - self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY) os.chdir(self.tmp_dir) def tearDown(self): @@ -84,7 +75,6 @@ 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'} dist = Distribution(metadata) - dist.script_name = 'setup.py' dist.packages = ['somecode'] dist.include_package_data = True cmd = sdist(dist) diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -114,7 +114,7 @@ GecodeInt GecodeKernel -- sys.platform == 'win32' [extension=fast_taunt] -name = three.fast_taunt +name = two.fast_taunt sources = cxx_src/utils_taunt.cxx cxx_src/python_module.cxx include_dirs = /usr/include/gecode @@ -305,7 +305,7 @@ self.assertEqual(ext.extra_link_args, ['`gcc -print-file-name=libgcc.a`', '-shared']) - ext = ext_modules.get('three.fast_taunt') + ext = ext_modules.get('two.fast_taunt') self.assertEqual(ext.sources, ['cxx_src/utils_taunt.cxx', 'cxx_src/python_module.cxx']) self.assertEqual(ext.include_dirs, diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1099,7 +1099,7 @@ response = input(message) response = response.strip().lower() if response not in options: - print('invalid response: %r' % response) + print('invalid response:', repr(response)) print('choose one of', ', '.join(repr(o) for o in options)) else: return response diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1780,6 +1780,13 @@ install.initialize_options(self) self.warn_dir=0 + # Customize subcommands to not install an egg-info file for Python + sub_commands = [('install_lib', install.has_lib), + ('install_headers', install.has_headers), + ('install_scripts', install.has_scripts), + ('install_data', install.has_data)] + + class PyBuildInstallLib(install_lib): # Do exactly what install_lib does but make sure correct access modes get # set on installed directories and files. All installed files with get -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:11:07 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:11:07 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_The_change_done_for_=231064?= =?utf8?q?5_deserves_a_NEWS_entry?= Message-ID: http://hg.python.org/cpython/rev/af7bc95e5b1e changeset: 70733:af7bc95e5b1e user: ?ric Araujo date: Thu Jun 09 14:10:07 2011 +0200 summary: The change done for #10645 deserves a NEWS entry files: Misc/NEWS | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -781,6 +781,9 @@ Build ----- +- Issue #10645: Installing Python does no longer create a + Python-X.Y.Z-pyX.Y.egg-info file in the lib-dynload directory. + - Do not accidentally include the directory containing sqlite.h twice when building sqlite3. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 14:27:31 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 14:27:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_a_few_misus?= =?utf8?q?es_of_=3Aoption=3A_I_missed_in_r86521=2E?= Message-ID: http://hg.python.org/cpython/rev/7164bdfa0b0b changeset: 70734:7164bdfa0b0b branch: 2.7 parent: 70717:fd477fe2da05 user: ?ric Araujo date: Thu Jun 09 14:26:10 2011 +0200 summary: Fix a few misuses of :option: I missed in r86521. Extract of the commit message: Fix usage of :option: in the docs (#9312). :option: is used to create a link to an option of python, not to mark up any instance of any arbitrary command-line option. These were changed to ````. files: Doc/c-api/intro.rst | 4 ++-- Doc/license.rst | 4 ++-- Doc/using/cmdline.rst | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -594,8 +594,8 @@ Compiling the interpreter with the :cmacro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :cmacro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :cmacro:`_DEBUG` macro. When :cmacro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -889,7 +889,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -918,7 +918,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -569,7 +569,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 16:45:13 2011 From: python-checkins at python.org (eric.araujo) Date: Thu, 09 Jun 2011 16:45:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_doc_fixes_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/6feb5c87a7fb changeset: 70735:6feb5c87a7fb parent: 70733:af7bc95e5b1e parent: 70730:42cd9776017d user: ?ric Araujo date: Thu Jun 09 16:28:19 2011 +0200 summary: Merge doc fixes from 3.2 files: Doc/c-api/intro.rst | 4 ++-- Doc/distutils/install.rst | 15 +++++++++------ Doc/distutils/introduction.rst | 10 ++++++++-- Doc/documenting/markup.rst | 11 ++++++----- Doc/library/builtins.rst | 4 +++- Doc/library/constants.rst | 2 ++ Doc/license.rst | 4 ++-- Doc/using/cmdline.rst | 2 +- 8 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -588,8 +588,8 @@ Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/distutils/install.rst b/Doc/distutils/install.rst --- a/Doc/distutils/install.rst +++ b/Doc/distutils/install.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,7 +7,9 @@ This module provides direct access to all 'built-in' identifiers of Python; for example, ``builtins.open`` is the full name for the built-in function -:func:`open`. +:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for +documentation. + This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -1,3 +1,5 @@ +.. _built-in-consts: + Built-in Constants ================== diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -847,7 +847,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -876,7 +876,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -511,7 +511,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 17:01:23 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 17:01:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Correction_to_8?= =?utf8?q?8e318166eaf_-_Issue_=2311583?= Message-ID: http://hg.python.org/cpython/rev/d40609dd01e0 changeset: 70736:d40609dd01e0 branch: 3.2 parent: 70730:42cd9776017d user: Brian Curtin date: Thu Jun 09 09:10:38 2011 -0500 summary: Correction to 88e318166eaf - Issue #11583 Rather than wrapping the C _isdir function in a Python function, just import the C _isdir function directly. Additionally, add in the docstring which was left out. files: Lib/ntpath.py | 8 +++----- Modules/posixmodule.c | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -679,9 +679,7 @@ # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. - from nt import _isdir + from nt import _isdir as isdir except ImportError: - from genericpath import isdir as _isdir - -def isdir(path): - return _isdir(path) + # Use genericpath.isdir as imported above. + pass diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2820,6 +2820,9 @@ info.nFileIndexLow); } +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -8091,7 +8094,7 @@ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, - {"_isdir", posix__isdir, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 17:01:24 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 17:01:24 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/7f218ed216e2 changeset: 70737:7f218ed216e2 parent: 70735:6feb5c87a7fb parent: 70736:d40609dd01e0 user: Brian Curtin date: Thu Jun 09 09:46:21 2011 -0500 summary: Merge 3.2 files: Lib/ntpath.py | 8 +++----- Modules/posixmodule.c | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -679,9 +679,7 @@ # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. - from nt import _isdir + from nt import _isdir as isdir except ImportError: - from genericpath import isdir as _isdir - -def isdir(path): - return _isdir(path) + # Use genericpath.isdir as imported above. + pass diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2961,6 +2961,9 @@ info.nFileIndexLow); } +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -9597,7 +9600,7 @@ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, - {"_isdir", posix__isdir, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 17:01:28 2011 From: python-checkins at python.org (brian.curtin) Date: Thu, 09 Jun 2011 17:01:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Correction_to_f?= =?utf8?q?1509fc75435_-_Issue_=2311583?= Message-ID: http://hg.python.org/cpython/rev/fe813f5711a5 changeset: 70738:fe813f5711a5 branch: 2.7 parent: 70734:7164bdfa0b0b user: Brian Curtin date: Thu Jun 09 10:00:42 2011 -0500 summary: Correction to f1509fc75435 - Issue #11583 Rather than wrapping the C _isdir function in a Python function, just import the C _isdir function directly. Additionally, add in the docstring which was left out. files: Lib/ntpath.py | 8 +++----- Modules/posixmodule.c | 5 ++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -527,9 +527,7 @@ # attribute to tell whether or not the path is a directory. # This is overkill on Windows - just pass the path to GetFileAttributes # and check the attribute from there. - from nt import _isdir + from nt import _isdir as isdir except ImportError: - from genericpath import isdir as _isdir - -def isdir(path): - return _isdir(path) + # Use genericpath.isdir as imported above. + pass diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4200,6 +4200,9 @@ return result; } +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -9003,7 +9006,7 @@ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, - {"_isdir", posix__isdir, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 17:55:33 2011 From: python-checkins at python.org (vinay.sajip) Date: Thu, 09 Jun 2011 17:55:33 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMTY4?= =?utf8?q?=3A_SysLogHandler_now_allows_NUL_termination_to_be_controlled_us?= =?utf8?q?ing_a?= Message-ID: http://hg.python.org/cpython/rev/260b84851d1f changeset: 70739:260b84851d1f branch: 3.2 parent: 70736:d40609dd01e0 user: Vinay Sajip date: Thu Jun 09 16:50:49 2011 +0100 summary: Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. files: Lib/logging/handlers.py | 6 +++++- Misc/NEWS | 3 +++ 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -766,6 +766,8 @@ """ return self.priority_map.get(levelName, "warning") + append_nul = True # some old syslog daemons expect a NUL terminator + def emit(self, record): """ Emit a record. @@ -773,7 +775,9 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) + '\000' + msg = self.format(record) + if self.append_nul: + msg += '\000' """ We need to convert record level to lowercase, maybe this will change in the future. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Library ------- +- Issue #12168: SysLogHandler now allows NUL termination to be controlled using + a new 'append_nul' attribute on the handler. + - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes instead of os.stat. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 17:55:55 2011 From: python-checkins at python.org (vinay.sajip) Date: Thu, 09 Jun 2011 17:55:55 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merged_fix_for_issue_=2312168_from_3=2E2=2E?= Message-ID: http://hg.python.org/cpython/rev/ac1217099b3f changeset: 70740:ac1217099b3f parent: 70737:7f218ed216e2 parent: 70739:260b84851d1f user: Vinay Sajip date: Thu Jun 09 16:55:23 2011 +0100 summary: Merged fix for issue #12168 from 3.2. files: Lib/logging/handlers.py | 6 +++++- Lib/test/test_logging.py | 8 ++++++-- Misc/NEWS | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -769,6 +769,8 @@ """ return self.priority_map.get(levelName, "warning") + append_nul = True # some old syslog daemons expect a NUL terminator + def emit(self, record): """ Emit a record. @@ -776,7 +778,9 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) + '\000' + msg = self.format(record) + if self.append_nul: + msg += '\000' """ We need to convert record level to lowercase, maybe this will change in the future. diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1399,8 +1399,7 @@ pointing to that server's address and port.""" BaseTest.setUp(self) addr = ('localhost', 0) - self.server = server = TestUDPServer(addr, self.handle_datagram, - 0.01) + self.server = server = TestUDPServer(addr, self.handle_datagram, 0.01) server.start() server.ready.wait() self.sock_hdlr = logging.handlers.DatagramHandler('localhost', @@ -1478,6 +1477,11 @@ logger.error("sp\xe4m") self.handled.wait() self.assertEqual(self.log_output, b'<11>\xef\xbb\xbfsp\xc3\xa4m\x00') + self.handled.clear() + self.sl_hdlr.append_nul = False + logger.error("sp\xe4m") + self.handled.wait() + self.assertEqual(self.log_output, b'<11>\xef\xbb\xbfsp\xc3\xa4m') @unittest.skipUnless(threading, 'Threading required for this test.') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #12168: SysLogHandler now allows NUL termination to be controlled using + a new 'append_nul' attribute on the handler. + - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes instead of os.stat. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 18:34:41 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 18:34:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=2310424=3A_argument_names_?= =?utf8?q?are_now_included_in_the_missing_argument_message?= Message-ID: http://hg.python.org/cpython/rev/cab204a79e09 changeset: 70741:cab204a79e09 user: R David Murray date: Thu Jun 09 12:34:07 2011 -0400 summary: #10424: argument names are now included in the missing argument message Fix and initial test patch by Michele Orr?. files: Lib/argparse.py | 15 ++---- Lib/test/test_argparse.py | 61 +++++++++++++++++++++++++++ Misc/NEWS | 3 + 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1969,17 +1969,12 @@ # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) - # if we didn't use all the Positional objects, there were too few - # arg strings supplied. - if positionals: - self.error(_('too few arguments')) - # make sure all required actions were present - for action in self._actions: - if action.required: - if action not in seen_actions: - name = _get_action_name(action) - self.error(_('argument %s is required') % name) + required_actions = [_get_action_name(action) for action in self._actions + if action.required and action not in seen_actions] + if required_actions: + self.error(_('the following arguments are required: %s') % + ', '.join(required_actions)) # make sure all required groups had one option present for group in self._mutually_exclusive_groups: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4480,6 +4480,67 @@ else: self.fail() +# ========================= +# MessageContentError tests +# ========================= + +class TestMessageContentError(TestCase): + + def test_missing_argument_name_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos', type=str) + parser.add_argument('-req_opt', type=int, required=True) + parser.add_argument('need_one', type=str, nargs='+') + + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['myXargument']) + msg = str(cm.exception) + self.assertNotIn(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['myXargument', '-req_opt=1']) + msg = str(cm.exception) + self.assertNotIn(msg, 'req_pos') + self.assertNotIn(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + + def test_optional_optional_not_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos', type=str) + parser.add_argument('--req_opt', type=int, required=True) + parser.add_argument('--opt_opt', type=bool, nargs='?', + default=True) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertNotIn(msg, 'opt_opt') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['--req_opt=1']) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertNotIn(msg, 'req_opt') + self.assertNotIn(msg, 'opt_opt') + + def test_optional_positional_not_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos') + parser.add_argument('optional_positional', nargs='?', default='eggs') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertNotIn(msg, 'optional_positional') + + # ====================== # parse_known_args tests # ====================== diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #10424: Argparse now includes the names of the missing required + arguments in the missing arguments error message. + - Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 19:43:22 2011 From: python-checkins at python.org (vinay.sajip) Date: Thu, 09 Jun 2011 19:43:22 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Merged_upstream_changes=2E?= Message-ID: http://hg.python.org/cpython/rev/870c14213384 changeset: 70743:870c14213384 parent: 70742:8582d5ea9aaa parent: 70741:cab204a79e09 user: Vinay Sajip date: Thu Jun 09 18:43:11 2011 +0100 summary: Merged upstream changes. files: Lib/argparse.py | 15 ++---- Lib/test/test_argparse.py | 61 +++++++++++++++++++++++++++ Misc/NEWS | 3 + 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1969,17 +1969,12 @@ # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) - # if we didn't use all the Positional objects, there were too few - # arg strings supplied. - if positionals: - self.error(_('too few arguments')) - # make sure all required actions were present - for action in self._actions: - if action.required: - if action not in seen_actions: - name = _get_action_name(action) - self.error(_('argument %s is required') % name) + required_actions = [_get_action_name(action) for action in self._actions + if action.required and action not in seen_actions] + if required_actions: + self.error(_('the following arguments are required: %s') % + ', '.join(required_actions)) # make sure all required groups had one option present for group in self._mutually_exclusive_groups: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4480,6 +4480,67 @@ else: self.fail() +# ========================= +# MessageContentError tests +# ========================= + +class TestMessageContentError(TestCase): + + def test_missing_argument_name_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos', type=str) + parser.add_argument('-req_opt', type=int, required=True) + parser.add_argument('need_one', type=str, nargs='+') + + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['myXargument']) + msg = str(cm.exception) + self.assertNotIn(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['myXargument', '-req_opt=1']) + msg = str(cm.exception) + self.assertNotIn(msg, 'req_pos') + self.assertNotIn(msg, 'req_opt') + self.assertRegex(msg, 'need_one') + + def test_optional_optional_not_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos', type=str) + parser.add_argument('--req_opt', type=int, required=True) + parser.add_argument('--opt_opt', type=bool, nargs='?', + default=True) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertRegex(msg, 'req_opt') + self.assertNotIn(msg, 'opt_opt') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['--req_opt=1']) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertNotIn(msg, 'req_opt') + self.assertNotIn(msg, 'opt_opt') + + def test_optional_positional_not_in_message(self): + parser = ErrorRaisingArgumentParser(prog='PROG', usage='') + parser.add_argument('req_pos') + parser.add_argument('optional_positional', nargs='?', default='eggs') + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args([]) + msg = str(cm.exception) + self.assertRegex(msg, 'req_pos') + self.assertNotIn(msg, 'optional_positional') + + # ====================== # parse_known_args tests # ====================== diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #10424: Argparse now includes the names of the missing required + arguments in the missing arguments error message. + - Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 19:43:21 2011 From: python-checkins at python.org (vinay.sajip) Date: Thu, 09 Jun 2011 19:43:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Made_time_formats_in_Format?= =?utf8?q?ter_more_configurable=2E?= Message-ID: http://hg.python.org/cpython/rev/8582d5ea9aaa changeset: 70742:8582d5ea9aaa parent: 70740:ac1217099b3f user: Vinay Sajip date: Thu Jun 09 18:42:19 2011 +0100 summary: Made time formats in Formatter more configurable. files: Lib/logging/__init__.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -467,6 +467,9 @@ self._fmt = self._style._fmt self.datefmt = datefmt + default_time_format = '%Y-%m-%d %H:%M:%S' + default_msec_format = '%s,%03d' + def formatTime(self, record, datefmt=None): """ Return the creation time of the specified LogRecord as formatted text. @@ -489,8 +492,8 @@ if datefmt: s = time.strftime(datefmt, ct) else: - t = time.strftime("%Y-%m-%d %H:%M:%S", ct) - s = "%s,%03d" % (t, record.msecs) # the use of % here is internal + t = time.strftime(self.default_time_format, ct) + s = self.default_msec_format % (t, record.msecs) return s def formatException(self, ei): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 21:21:49 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 21:21:49 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzEyMjgzOiBGaXhl?= =?utf8?q?d_regression_in_smtplib_quoting_of_leading_dots_in_DATA=2E?= Message-ID: http://hg.python.org/cpython/rev/077b016e4a6d changeset: 70744:077b016e4a6d branch: 3.2 parent: 70739:260b84851d1f user: R David Murray date: Thu Jun 09 15:05:57 2011 -0400 summary: #12283: Fixed regression in smtplib quoting of leading dots in DATA. I unfortunately introduced the regression when I refactored the code, and there were no tests of quoting so it wasn't caught. Now there is one. files: Lib/smtplib.py | 2 +- Lib/test/test_smtplib.py | 15 +++++++++++++++ Misc/NEWS | 2 ++ 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -162,7 +162,7 @@ re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) def _quote_periods(bindata): - return re.sub(br'(?m)^\.', '..', bindata) + return re.sub(br'(?m)^\.', b'..', bindata) def _fix_eols(data): return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -278,6 +278,21 @@ mexpect = '%s%s\n%s' % (MSG_BEGIN, m.decode('ascii'), MSG_END) self.assertEqual(self.output.getvalue(), mexpect) + def testSendNeedingDotQuote(self): + # Issue 12283 + m = '.A test\n.mes.sage.' + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) + smtp.sendmail('John', 'Sally', m) + # XXX (see comment in testSend) + time.sleep(0.01) + smtp.quit() + + self.client_evt.set() + self.serv_evt.wait() + self.output.flush() + mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END) + self.assertEqual(self.output.getvalue(), mexpect) + def testSendMessage(self): m = email.mime.text.MIMEText('A test message') smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,8 @@ Library ------- +- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. + - Issue #12168: SysLogHandler now allows NUL termination to be controlled using a new 'append_nul' attribute on the handler. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 21:21:50 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 21:21:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=2312283=3A_Fixed_regression_in_smtplib_quoting_of_lea?= =?utf8?q?ding_dots_in_DATA=2E?= Message-ID: http://hg.python.org/cpython/rev/cedceeb45030 changeset: 70745:cedceeb45030 parent: 70743:870c14213384 parent: 70744:077b016e4a6d user: R David Murray date: Thu Jun 09 15:21:02 2011 -0400 summary: merge #12283: Fixed regression in smtplib quoting of leading dots in DATA. files: Lib/smtplib.py | 2 +- Lib/test/test_smtplib.py | 15 +++++++++++++++ Misc/NEWS | 2 ++ 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -162,7 +162,7 @@ re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) def _quote_periods(bindata): - return re.sub(br'(?m)^\.', '..', bindata) + return re.sub(br'(?m)^\.', b'..', bindata) def _fix_eols(data): return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -278,6 +278,21 @@ mexpect = '%s%s\n%s' % (MSG_BEGIN, m.decode('ascii'), MSG_END) self.assertEqual(self.output.getvalue(), mexpect) + def testSendNeedingDotQuote(self): + # Issue 12283 + m = '.A test\n.mes.sage.' + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) + smtp.sendmail('John', 'Sally', m) + # XXX (see comment in testSend) + time.sleep(0.01) + smtp.quit() + + self.client_evt.set() + self.serv_evt.wait() + self.output.flush() + mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END) + self.assertEqual(self.output.getvalue(), mexpect) + def testSendMessage(self): m = email.mime.text.MIMEText('A test message') smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,8 @@ Library ------- +- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. + - Issue #10424: Argparse now includes the names of the missing required arguments in the missing arguments error message. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 22:02:06 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 22:02:06 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzEwNjk0OiB6aXBm?= =?utf8?q?ile_now_ignores_garbage_at_the_end_of_a_zipfile=2E?= Message-ID: http://hg.python.org/cpython/rev/7530b141c20f changeset: 70746:7530b141c20f branch: 3.2 parent: 70744:077b016e4a6d user: R David Murray date: Thu Jun 09 15:50:51 2011 -0400 summary: #10694: zipfile now ignores garbage at the end of a zipfile. Original fix by 'rep', final patch (with tests) by Xuanji Li. files: Lib/test/test_zipfile.py | 18 ++++++++++++++++++ Lib/zipfile.py | 16 +++++++--------- Misc/NEWS | 2 ++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -351,6 +351,24 @@ with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -246,16 +246,14 @@ # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,8 @@ Library ------- +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. - Issue #12168: SysLogHandler now allows NUL termination to be controlled using -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 22:02:08 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 22:02:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_=2310694=3A_zipfile_now_ignores_garbage_at_the_end_of_?= =?utf8?q?a_zipfile=2E?= Message-ID: http://hg.python.org/cpython/rev/2e49722c7263 changeset: 70747:2e49722c7263 parent: 70745:cedceeb45030 parent: 70746:7530b141c20f user: R David Murray date: Thu Jun 09 15:52:31 2011 -0400 summary: Merge #10694: zipfile now ignores garbage at the end of a zipfile. files: Lib/test/test_zipfile.py | 18 ++++++++++++++++++ Lib/zipfile.py | 16 +++++++--------- Misc/NEWS | 2 ++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -345,6 +345,24 @@ with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -246,16 +246,14 @@ # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,8 @@ Library ------- +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. - Issue #10424: Argparse now includes the names of the missing required -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 9 22:02:09 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 09 Jun 2011 22:02:09 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzEwNjk0OiB6aXBm?= =?utf8?q?ile_now_ignores_garbage_at_the_end_of_a_zipfile=2E?= Message-ID: http://hg.python.org/cpython/rev/cc3255a707c7 changeset: 70748:cc3255a707c7 branch: 2.7 parent: 70738:fe813f5711a5 user: R David Murray date: Thu Jun 09 16:01:09 2011 -0400 summary: #10694: zipfile now ignores garbage at the end of a zipfile. Original fix by 'rep', final patch (with tests) by Xuanji Li. files: Lib/test/test_zipfile.py | 18 ++++++++++++++++++ Lib/zipfile.py | 16 +++++++--------- Misc/NEWS | 2 ++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -335,6 +335,24 @@ with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -236,16 +236,14 @@ # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,8 @@ Library ------- +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes instead of os.stat. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 00:56:02 2011 From: python-checkins at python.org (brian.curtin) Date: Fri, 10 Jun 2011 00:56:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Removed_a_Windows_9x_trick_?= =?utf8?q?used_before_LoadLibraryExW=2E?= Message-ID: http://hg.python.org/cpython/rev/f8aacfd3b070 changeset: 70749:f8aacfd3b070 parent: 70747:2e49722c7263 user: Brian Curtin date: Thu Jun 09 17:55:54 2011 -0500 summary: Removed a Windows 9x trick used before LoadLibraryExW. Windows 9x has long been unsupported and the result of GetFullPathName was not even being used in the first place. files: Python/dynload_win.c | 25 ++++++++----------------- 1 files changed, 8 insertions(+), 17 deletions(-) diff --git a/Python/dynload_win.c b/Python/dynload_win.c --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -185,28 +185,19 @@ { HINSTANCE hDLL = NULL; - wchar_t pathbuf[260]; unsigned int old_mode; ULONG_PTR cookie = 0; - /* We use LoadLibraryEx so Windows looks for dependent DLLs - in directory of pathname first. However, Windows95 - can sometimes not work correctly unless the absolute - path is used. If GetFullPathName() fails, the LoadLibrary - will certainly fail too, so use its error code */ - + /* Don't display a message box when Python can't load a DLL */ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); - if (GetFullPathNameW(PyUnicode_AS_UNICODE(pathname), - sizeof(pathbuf) / sizeof(pathbuf[0]), - pathbuf, - NULL)) { - ULONG_PTR cookie = _Py_ActivateActCtx(); - /* XXX This call doesn't exist in Windows CE */ - hDLL = LoadLibraryExW(PyUnicode_AS_UNICODE(pathname), NULL, - LOAD_WITH_ALTERED_SEARCH_PATH); - _Py_DeactivateActCtx(cookie); - } + cookie = _Py_ActivateActCtx(); + /* We use LoadLibraryEx so Windows looks for dependent DLLs + in directory of pathname first. */ + /* XXX This call doesn't exist in Windows CE */ + hDLL = LoadLibraryExW(PyUnicode_AS_UNICODE(pathname), NULL, + LOAD_WITH_ALTERED_SEARCH_PATH); + _Py_DeactivateActCtx(cookie); /* restore old error mode settings */ SetErrorMode(old_mode); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 01:40:14 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 01:40:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=238407=3A_signal=2Es?= =?utf8?q?igwait=28=29_releases_the_GIL?= Message-ID: http://hg.python.org/cpython/rev/a5c8b6ebe895 changeset: 70750:a5c8b6ebe895 user: Victor Stinner date: Fri Jun 10 01:39:53 2011 +0200 summary: Issue #8407: signal.sigwait() releases the GIL Initial patch by Charles-Fran?ois Natali. files: Lib/test/test_signal.py | 19 +++++++++++++++++++ Modules/signalmodule.c | 2 ++ 2 files changed, 21 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -607,6 +607,25 @@ signal.alarm(1) self.assertEqual(signal.sigwait([signal.SIGALRM]), signal.SIGALRM) + @unittest.skipUnless(hasattr(signal, 'sigwait'), + 'need signal.sigwait()') + @unittest.skipIf(threading is None, "test needs threading module") + def test_sigwait_thread(self): + signum = signal.SIGUSR1 + old_handler = signal.signal(signum, self.handler) + self.addCleanup(signal.signal, signum, old_handler) + + def kill_later(): + time.sleep(1) + os.kill(os.getpid(), signum) + + killer = threading.Thread(target=kill_later) + killer.start() + try: + self.assertEqual(signal.sigwait([signum]), signum) + finally: + killer.join() + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') def test_pthread_sigmask_arguments(self): diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -662,7 +662,9 @@ if (iterable_to_sigset(signals, &set)) return NULL; + Py_BEGIN_ALLOW_THREADS err = sigwait(&set, &signum); + Py_END_ALLOW_THREADS if (err) { errno = err; return PyErr_SetFromErrno(PyExc_OSError); -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Fri Jun 10 05:06:20 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 10 Jun 2011 05:06:20 +0200 Subject: [Python-checkins] Daily reference leaks (a5c8b6ebe895): sum=76 Message-ID: results for a5c8b6ebe895 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 test_pydoc leaked [0, 0, -323] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogQZzQT3', '-x'] From python-checkins at python.org Fri Jun 10 07:33:12 2011 From: python-checkins at python.org (ross.lagerwall) Date: Fri, 10 Jun 2011 07:33:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=239344=3A_Add_os=2Eg?= =?utf8?q?etgrouplist=28=29=2E?= Message-ID: http://hg.python.org/cpython/rev/9ebee3211be9 changeset: 70751:9ebee3211be9 user: Ross Lagerwall date: Fri Jun 10 07:30:30 2011 +0200 summary: Issue #9344: Add os.getgrouplist(). files: Doc/library/os.rst | 11 + Lib/test/test_posix.py | 15 + Modules/posixmodule.c | 67 +++ configure | 526 +++++++++++++++------------- configure.in | 4 +- pyconfig.h.in | 3 + 6 files changed, 371 insertions(+), 255 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -219,6 +219,17 @@ Availability: Unix. +.. function:: getgrouplist(user, group) + + Return list of group ids that *user* belongs to. If *group* is not in the + list, it is included; typically, *group* is specified as the group ID + field from the password record for *user*. + + Availability: Unix. + + .. versionadded:: 3.3 + + .. function:: getgroups() Return list of supplemental group ids associated with the current process. diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -569,6 +569,21 @@ os.chdir(curdir) support.rmtree(base_path) + @unittest.skipUnless(hasattr(posix, 'getgrouplist'), "test needs posix.getgrouplist()") + @unittest.skipUnless(hasattr(pwd, 'getpwuid'), "test needs pwd.getpwuid()") + @unittest.skipUnless(hasattr(os, 'getuid'), "test needs os.getuid()") + def test_getgrouplist(self): + with os.popen('id -G') as idg: + groups = idg.read().strip() + + if not groups: + raise unittest.SkipTest("need working 'id -G'") + + self.assertEqual( + set([int(x) for x in groups.split()]), + set(posix.getgrouplist(pwd.getpwuid(os.getuid())[0], + pwd.getpwuid(os.getuid())[3]))) + @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()") def test_getgroups(self): with os.popen('id -G') as idg: diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4672,6 +4672,70 @@ return PyLong_FromPid(getpid()); } +#ifdef HAVE_GETGROUPLIST +PyDoc_STRVAR(posix_getgrouplist__doc__, +"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ +Returns a list of groups to which a user belongs.\n\n\ + user: username to lookup\n\ + group: base group id of the user"); + +static PyObject * +posix_getgrouplist(PyObject *self, PyObject *args) +{ +#ifdef NGROUPS_MAX +#define MAX_GROUPS NGROUPS_MAX +#else + /* defined to be 16 on Solaris7, so this should be a small number */ +#define MAX_GROUPS 64 +#endif + + const char *user; + int i, ngroups; + PyObject *list; +#ifdef __APPLE__ + int *groups, basegid; +#else + gid_t *groups, basegid; +#endif + ngroups = MAX_GROUPS; + + if (!PyArg_ParseTuple(args, "si", &user, &basegid)) + return NULL; + +#ifdef __APPLE__ + groups = PyMem_Malloc(ngroups * sizeof(int)); +#else + groups = PyMem_Malloc(ngroups * sizeof(gid_t)); +#endif + if (groups == NULL) + return PyErr_NoMemory(); + + if (getgrouplist(user, basegid, groups, &ngroups) == -1) { + PyMem_Del(groups); + return posix_error(); + } + + list = PyList_New(ngroups); + if (list == NULL) { + PyMem_Del(groups); + return NULL; + } + + for (i = 0; i < ngroups; i++) { + PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); + if (o == NULL) { + Py_DECREF(list); + PyMem_Del(groups); + return NULL; + } + PyList_SET_ITEM(list, i, o); + } + + PyMem_Del(groups); + + return list; +} +#endif #ifdef HAVE_GETGROUPS PyDoc_STRVAR(posix_getgroups__doc__, @@ -9383,6 +9447,9 @@ #ifdef HAVE_GETGID {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, #endif /* HAVE_GETGID */ +#ifdef HAVE_GETGROUPLIST + {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, +#endif #ifdef HAVE_GETGROUPS {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, #endif diff --git a/configure b/configure --- a/configure +++ b/configure @@ -1,13 +1,13 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for python 3.3. +# Generated by GNU Autoconf 2.67 for python 3.3. # # Report bugs to . # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -319,7 +319,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -359,19 +359,19 @@ fi # as_fn_arith -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -533,7 +533,7 @@ exec 6>&1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -833,8 +833,9 @@ fi case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -879,7 +880,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -905,7 +906,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1109,7 +1110,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1125,7 +1126,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1155,8 +1156,8 @@ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information." + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) @@ -1164,7 +1165,7 @@ # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1182,13 +1183,13 @@ if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" + as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1211,7 +1212,7 @@ [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1225,8 +1226,8 @@ if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1241,9 +1242,9 @@ ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error "working directory cannot be determined" + as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error "pwd does not report name of working directory" + as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1282,11 +1283,11 @@ fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1326,7 +1327,7 @@ --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1511,9 +1512,9 @@ if $ac_init_version; then cat <<\_ACEOF python configure 3.3 -generated by GNU Autoconf 2.65 - -Copyright (C) 2009 Free Software Foundation, Inc. +generated by GNU Autoconf 2.67 + +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1629,7 +1630,7 @@ mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { + test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1653,10 +1654,10 @@ ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1692,7 +1693,7 @@ else ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -1715,17 +1716,15 @@ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( cat <<\_ASBOX -## -------------------------------------- ## +( $as_echo "## -------------------------------------- ## ## Report this to http://bugs.python.org/ ## -## -------------------------------------- ## -_ASBOX +## -------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -1789,7 +1788,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1820,7 +1819,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1874,7 +1873,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 $as_echo_n "checking for uint$2_t... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1904,8 +1903,7 @@ esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - eval as_val=\$$3 - if test "x$as_val" = x""no; then : + if eval test \"x\$"$3"\" = x"no"; then : else break @@ -1928,7 +1926,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 $as_echo_n "checking for int$2_t... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1979,8 +1977,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - eval as_val=\$$3 - if test "x$as_val" = x""no; then : + if eval test \"x\$"$3"\" = x"no"; then : else break @@ -2180,7 +2177,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2248,7 +2245,7 @@ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } -if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$4+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2296,15 +2293,18 @@ } # ac_fn_c_check_member -# ac_fn_c_check_decl LINENO SYMBOL VAR -# ------------------------------------ -# Tests whether SYMBOL is declared, setting cache variable VAR accordingly. +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5 -$as_echo_n "checking whether $2 is declared... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2313,8 +2313,12 @@ int main () { -#ifndef $2 - (void) $2; +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif #endif ; @@ -2339,7 +2343,7 @@ running configure, to aid debugging if configure makes a mistake. It was created by python $as_me 3.3, which was -generated by GNU Autoconf 2.65. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2449,11 +2453,9 @@ { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( @@ -2487,11 +2489,9 @@ ) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do @@ -2504,11 +2504,9 @@ echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## + $as_echo "## ------------------- ## ## File substitutions. ## -## ------------------- ## -_ASBOX +## ------------------- ##" echo for ac_var in $ac_subst_files do @@ -2522,11 +2520,9 @@ fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo cat confdefs.h echo @@ -2581,7 +2577,12 @@ ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2596,7 +2597,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -2672,7 +2677,7 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2832,7 +2837,7 @@ UNIVERSALSDK=$enableval if test ! -d "${UNIVERSALSDK}" then - as_fn_error "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 + as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5 fi ;; esac @@ -3224,7 +3229,7 @@ # If the user switches compilers, we can't believe the cache if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC" then - as_fn_error "cached CC is different -- throw away $cache_file + as_fn_error $? "cached CC is different -- throw away $cache_file (it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5 fi @@ -3534,8 +3539,8 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "no acceptable C compiler found in \$PATH -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -3649,9 +3654,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "C compiler cannot create executables -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3693,8 +3697,8 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3751,9 +3755,9 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. +as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -3804,8 +3808,8 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of object files: cannot compile -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -4288,7 +4292,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4304,11 +4308,11 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -4347,7 +4351,7 @@ # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -4363,18 +4367,18 @@ ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c @@ -4435,7 +4439,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP @@ -4501,7 +4505,7 @@ done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP @@ -4633,8 +4637,7 @@ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -5252,16 +5255,22 @@ esac ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - for ac_t in install-sh install.sh shtool; do - if test -f "$ac_dir/$ac_t"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/$ac_t -c" - break 2 - fi - done + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi done if test -z "$ac_aux_dir"; then - as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -5599,7 +5608,7 @@ ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc" else - as_fn_error "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 + as_fn_error $? "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5 fi @@ -6087,8 +6096,7 @@ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -6102,7 +6110,7 @@ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$as_ac_Header+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -6129,8 +6137,7 @@ eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF @@ -6655,9 +6662,8 @@ if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (int) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_int=0 fi @@ -6689,9 +6695,8 @@ if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (long) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_long=0 fi @@ -6723,9 +6728,8 @@ if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (void *) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_void_p=0 fi @@ -6757,9 +6761,8 @@ if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (short) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_short=0 fi @@ -6791,9 +6794,8 @@ if test "$ac_cv_type_float" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (float) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (float) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_float=0 fi @@ -6825,9 +6827,8 @@ if test "$ac_cv_type_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (double) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (double) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_double=0 fi @@ -6859,9 +6860,8 @@ if test "$ac_cv_type_fpos_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (fpos_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (fpos_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_fpos_t=0 fi @@ -6893,9 +6893,8 @@ if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (size_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (size_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_size_t=0 fi @@ -6927,9 +6926,8 @@ if test "$ac_cv_type_pid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (pid_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (pid_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_pid_t=0 fi @@ -6988,9 +6986,8 @@ if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (long long) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_long_long=0 fi @@ -7050,9 +7047,8 @@ if test "$ac_cv_type_long_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (long double) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (long double) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_long_double=0 fi @@ -7113,9 +7109,8 @@ if test "$ac_cv_type__Bool" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (_Bool) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (_Bool) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof__Bool=0 fi @@ -7162,9 +7157,8 @@ if test "$ac_cv_type_uintptr_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (uintptr_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (uintptr_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_uintptr_t=0 fi @@ -7204,9 +7198,8 @@ if test "$ac_cv_type_off_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (off_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (off_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_off_t=0 fi @@ -7267,9 +7260,8 @@ if test "$ac_cv_type_time_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (time_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (time_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_time_t=0 fi @@ -7340,9 +7332,8 @@ if test "$ac_cv_type_pthread_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (pthread_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (pthread_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_pthread_t=0 fi @@ -7429,7 +7420,7 @@ MACOSX_DEFAULT_ARCH="ppc" ;; *) - as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac else @@ -7441,7 +7432,7 @@ MACOSX_DEFAULT_ARCH="ppc64" ;; *) - as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5 + as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5 ;; esac @@ -7467,7 +7458,7 @@ $as_echo "yes" >&6; } if test $enable_shared = "yes" then - as_fn_error "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 + as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -8307,12 +8298,12 @@ withval=$with_dbmliborder; if test x$with_dbmliborder = xyes then -as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 +as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 else for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb then - as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 + as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5 fi done fi @@ -9285,7 +9276,7 @@ $as_echo "#define WITH_VALGRIND 1" >>confdefs.h else - as_fn_error "Valgrind support requested but headers not available" "$LINENO" 5 + as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5 fi @@ -9365,8 +9356,8 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ - futimens futimes \ - gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ + futimens futimes gai_strerror \ + getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \ @@ -9384,8 +9375,7 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10408,8 +10398,7 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10418,25 +10407,44 @@ done -for ac_func in dup2 getcwd strdup -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" +if test "x$ac_cv_func_dup2" = x""yes; then : + $as_echo "#define HAVE_DUP2 1" >>confdefs.h else case " $LIBOBJS " in - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" + *" dup2.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS dup2.$ac_objext" ;; esac fi -done + +ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" +if test "x$ac_cv_func_getcwd" = x""yes; then : + $as_echo "#define HAVE_GETCWD 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" getcwd.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS getcwd.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" +if test "x$ac_cv_func_strdup" = x""yes; then : + $as_echo "#define HAVE_STRDUP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strdup.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strdup.$ac_objext" + ;; +esac + +fi for ac_func in getpgrp @@ -11649,7 +11657,7 @@ then LIBM=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 $as_echo "set LIBM=\"$withval\"" >&6; } -else as_fn_error "proper usage is --with-libm=STRING" "$LINENO" 5 +else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 @@ -11673,7 +11681,7 @@ then LIBC=$withval { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 $as_echo "set LIBC=\"$withval\"" >&6; } -else as_fn_error "proper usage is --with-libc=STRING" "$LINENO" 5 +else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 @@ -11923,8 +11931,7 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -11936,8 +11943,7 @@ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -12200,7 +12206,7 @@ 15|30) ;; *) - as_fn_error "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; + as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 $as_echo "$enable_big_digits" >&6; } @@ -12251,9 +12257,8 @@ if test "$ac_cv_type_wchar_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "cannot compute sizeof (wchar_t) -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "cannot compute sizeof (wchar_t) +See \`config.log' for more details" "$LINENO" 5 ; } else ac_cv_sizeof_wchar_t=0 fi @@ -12622,8 +12627,8 @@ ;; #( *) - as_fn_error "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac @@ -12884,7 +12889,7 @@ have_readline=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13058,7 +13063,7 @@ have_readline=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext if test $have_readline = yes then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13980,6 +13985,7 @@ ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -14142,19 +14148,19 @@ (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -14350,7 +14356,7 @@ test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -14404,7 +14410,7 @@ # values after options handling. ac_log=" This file was extended by python $as_me 3.3, which was -generated by GNU Autoconf 2.65. Invocation command line was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -14466,10 +14472,10 @@ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ python config.status 3.3 -configured by $0, generated by GNU Autoconf 2.65, +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -14485,11 +14491,16 @@ while test $# != 0 do case $1 in - --*=*) + --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; *) ac_option=$1 ac_optarg=$2 @@ -14511,6 +14522,7 @@ $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -14523,7 +14535,7 @@ ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error "ambiguous option: \`$1' + as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -14532,7 +14544,7 @@ ac_cs_silent=: ;; # This is an error. - -*) as_fn_error "unrecognized option: \`$1' + -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -14591,7 +14603,7 @@ "Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;; "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;; - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -14628,7 +14640,7 @@ { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -14645,7 +14657,7 @@ fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\r' + ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi @@ -14659,18 +14671,18 @@ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14759,20 +14771,28 @@ else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// s/^[^=]*=[ ]*$// }' fi @@ -14800,7 +14820,7 @@ if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -14885,7 +14905,7 @@ _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error "could not setup config headers machinery" "$LINENO" 5 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -14898,7 +14918,7 @@ esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -14926,7 +14946,7 @@ [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -14953,7 +14973,7 @@ case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -15084,22 +15104,22 @@ $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 +which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} +which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -15110,19 +15130,19 @@ $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error "could not create -" "$LINENO" 5 + || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; @@ -15142,7 +15162,7 @@ ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -15163,7 +15183,7 @@ exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit $? + $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2541,8 +2541,8 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv faccessat fchmod fchmodat fchown fchownat \ fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \ - futimens futimes \ - gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ + futimens futimes gai_strerror \ + getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ if_nameindex \ initgroups kill killpg lchmod lchown lockf linkat lstat lutimes mbrtowc mkdirat mkfifo \ diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -305,6 +305,9 @@ /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ #undef HAVE_GETC_UNLOCKED +/* Define to 1 if you have the `getgrouplist' function. */ +#undef HAVE_GETGROUPLIST + /* Define to 1 if you have the `getgroups' function. */ #undef HAVE_GETGROUPS -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 09:36:51 2011 From: python-checkins at python.org (eli.bendersky) Date: Fri, 10 Jun 2011 09:36:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMjIz?= =?utf8?q?=3A_Typo_fix_in_datamodel_docs?= Message-ID: http://hg.python.org/cpython/rev/3bb5400f5bea changeset: 70752:3bb5400f5bea branch: 2.7 parent: 70748:cc3255a707c7 user: Eli Bendersky date: Fri Jun 10 10:36:34 2011 +0300 summary: Issue #12223: Typo fix in datamodel docs files: Doc/reference/datamodel.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2308,7 +2308,7 @@ * - In ``x * y``, if one operator is a sequence that implements sequence + In ``x * y``, if one operand is a sequence that implements sequence repetition, and the other is an integer (:class:`int` or :class:`long`), sequence repetition is invoked. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 12:49:50 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 12:49:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=238407=3A_Make_signa?= =?utf8?q?l=2Esigwait=28=29_tests_more_reliable?= Message-ID: http://hg.python.org/cpython/rev/a17710e27ea2 changeset: 70753:a17710e27ea2 parent: 70751:9ebee3211be9 user: Victor Stinner date: Fri Jun 10 12:48:13 2011 +0200 summary: Issue #8407: Make signal.sigwait() tests more reliable Block the signal before calling sigwait(). Use os.fork() to ensure that we have only one thread. Initial patch written by Charles-Fran?ois Natali. files: Lib/test/test_signal.py | 67 ++++++++++++++++++++++------ 1 files changed, 53 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -598,34 +598,73 @@ with self.assertRaises(ZeroDivisionError): signal.pthread_kill(current, signum) + def check_sigwait(self, test, signum): + # sigwait must be called with the signal blocked: since the current + # process might have several threads running, we fork() a child process + # to have a single thread. + pid = os.fork() + if pid == 0: + # child: block and wait the signal + try: + signal.signal(signum, self.handler) + signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + + # Do the tests + test(signum) + + # The handler must not be called on unblock + try: + signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) + except ZeroDivisionError: + print("the signal handler has been called", + file=sys.stderr) + os._exit(1) + + os._exit(0) + finally: + os._exit(1) + else: + # parent: let the child some time to wait, send him the signal, and + # check it correcty received it + self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') + @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') def test_sigwait(self): - old_handler = signal.signal(signal.SIGALRM, self.handler) - self.addCleanup(signal.signal, signal.SIGALRM, old_handler) + def test(signum): + signal.alarm(1) + received = signal.sigwait([signum]) + if received != signum: + print("sigwait() received %s, not %s" + % (received, signum), + file=sys.stderr) + os._exit(1) - signal.alarm(1) - self.assertEqual(signal.sigwait([signal.SIGALRM]), signal.SIGALRM) + self.check_sigwait(test, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') @unittest.skipIf(threading is None, "test needs threading module") + @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') def test_sigwait_thread(self): - signum = signal.SIGUSR1 - old_handler = signal.signal(signum, self.handler) - self.addCleanup(signal.signal, signum, old_handler) - - def kill_later(): + def kill_later(signum): + # wait until the main thread is waiting in sigwait() time.sleep(1) os.kill(os.getpid(), signum) - killer = threading.Thread(target=kill_later) - killer.start() - try: - self.assertEqual(signal.sigwait([signum]), signum) - finally: + def test(signum): + killer = threading.Thread(target=kill_later, args=(signum,)) + killer.start() + received = signal.sigwait([signum]) + if received != signum: + print("sigwait() received %s, not %s" % (received, signum), + file=sys.stderr) + os._exit(1) killer.join() + self.check_sigwait(test, signal.SIGUSR1) + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') def test_pthread_sigmask_arguments(self): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 13:53:45 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 13:53:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=238407=3A_write_erro?= =?utf8?q?r_message_on_sigwait_test_failure?= Message-ID: http://hg.python.org/cpython/rev/37a87b709403 changeset: 70754:37a87b709403 user: Victor Stinner date: Fri Jun 10 13:53:32 2011 +0200 summary: Issue #8407: write error message on sigwait test failure files: Lib/test/test_signal.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -619,10 +619,11 @@ print("the signal handler has been called", file=sys.stderr) os._exit(1) - + except BaseException as err: + print("error: {}".format(err), file=sys.stderr) + os._exit(1) + else: os._exit(0) - finally: - os._exit(1) else: # parent: let the child some time to wait, send him the signal, and # check it correcty received it -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 14:00:06 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 14:00:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_test=5Fplatform=3A_ignore_D?= =?utf8?q?eprecationWarning_on_popen=28=29_test?= Message-ID: http://hg.python.org/cpython/rev/5a745404facf changeset: 70755:5a745404facf user: Victor Stinner date: Fri Jun 10 13:59:59 2011 +0200 summary: test_platform: ignore DeprecationWarning on popen() test files: Lib/test/test_platform.py | 35 +++++++++++++++----------- 1 files changed, 20 insertions(+), 15 deletions(-) diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -1,8 +1,9 @@ -import sys import os -import unittest import platform import subprocess +import sys +import unittest +import warnings from test import support @@ -250,10 +251,12 @@ command = '"{}" -c "print(\'Hello\')"'.format(sys.executable) else: command = "'{}' -c 'print(\"Hello\")'".format(sys.executable) - with platform.popen(command) as stdout: - hello = stdout.read().strip() - stdout.close() - self.assertEqual(hello, "Hello") + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + with platform.popen(command) as stdout: + hello = stdout.read().strip() + stdout.close() + self.assertEqual(hello, "Hello") data = 'plop' if mswindows: @@ -261,15 +264,17 @@ else: command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'" command = command.format(sys.executable) - with platform.popen(command, 'w') as stdin: - stdout = stdin.write(data) - ret = stdin.close() - self.assertIsNotNone(ret) - if os.name == 'nt': - returncode = ret - else: - returncode = ret >> 8 - self.assertEqual(returncode, len(data)) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + with platform.popen(command, 'w') as stdin: + stdout = stdin.write(data) + ret = stdin.close() + self.assertIsNotNone(ret) + if os.name == 'nt': + returncode = ret + else: + returncode = ret >> 8 + self.assertEqual(returncode, len(data)) def test_main(): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 14:02:39 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 14:02:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=238407=3A_skip_sigwa?= =?utf8?q?it=28=29_tests_if_pthread=5Fsigmask=28=29_is_missing?= Message-ID: http://hg.python.org/cpython/rev/60b1ab4d0cd4 changeset: 70756:60b1ab4d0cd4 user: Victor Stinner date: Fri Jun 10 14:02:10 2011 +0200 summary: Issue #8407: skip sigwait() tests if pthread_sigmask() is missing The new tests now requires pthread_sigmask(). Skip the test if the function is missing, e.g. if Python is compiled without threads. files: Lib/test/test_signal.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -598,6 +598,8 @@ with self.assertRaises(ZeroDivisionError): signal.pthread_kill(current, signum) + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') def check_sigwait(self, test, signum): # sigwait must be called with the signal blocked: since the current # process might have several threads running, we fork() a child process -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 16:35:34 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 16:35:34 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4xKTogSXNzdWUgIzEwODAx?= =?utf8?q?=3A_Fix_test=5Funicode=5Ffilenames=28=29_of_test=5Fzipfile?= Message-ID: http://hg.python.org/cpython/rev/33b7428e65b4 changeset: 70757:33b7428e65b4 branch: 3.1 parent: 70644:d4a99fb5c2c5 user: Victor Stinner date: Fri Jun 10 16:32:54 2011 +0200 summary: Issue #10801: Fix test_unicode_filenames() of test_zipfile Just try to open files from the ZIP for reading, don't extract them to avoid UnicodeEncodeError if the filename is not encodable to the filesystem encoding (e.g. ASCII locale encoding). files: Lib/test/test_zipfile.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -405,7 +405,8 @@ zipfp = zipfile.ZipFile(fname) try: - zipfp.extractall() + for name in zipfp.namelist(): + zipfp.open(name).close() finally: zipfp.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 16:38:44 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 16:38:44 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_null_merge_3=2E1_=28patch_already_applied_to_3=2E2=29?= Message-ID: http://hg.python.org/cpython/rev/69c212deb969 changeset: 70758:69c212deb969 branch: 3.2 parent: 70746:7530b141c20f parent: 70757:33b7428e65b4 user: Victor Stinner date: Fri Jun 10 16:37:41 2011 +0200 summary: null merge 3.1 (patch already applied to 3.2) files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 16:38:45 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 10 Jun 2011 16:38:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_null_merge_3=2E2_=28patch_already_applied_to_3=2E3=29?= Message-ID: http://hg.python.org/cpython/rev/f89b42c35ceb changeset: 70759:f89b42c35ceb parent: 70756:60b1ab4d0cd4 parent: 70758:69c212deb969 user: Victor Stinner date: Fri Jun 10 16:38:38 2011 +0200 summary: null merge 3.2 (patch already applied to 3.3) files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:04 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging=3A_use_repr_to_di?= =?utf8?q?splay_projects_name_=283ebabfbf6fe3_followup=29?= Message-ID: http://hg.python.org/cpython/rev/9939be4e96be changeset: 70760:9939be4e96be parent: 70735:6feb5c87a7fb user: ?ric Araujo date: Fri Jun 10 03:10:53 2011 +0200 summary: Packaging: use repr to display projects name (3ebabfbf6fe3 followup) files: Lib/packaging/install.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -520,7 +520,7 @@ except InstallationConflict as e: if logger.isEnabledFor(logging.INFO): - projects = ['%s %s' % (p.name, p.version) for p in e.args[0]] + projects = ['%r %s' % (p.name, p.version) for p in e.args[0]] logger.info('%r conflicts with %s', project, ','.join(projects)) return True -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:05 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_*=2Eegg-info_from_Ma?= =?utf8?q?kefile=2Epre=2Ein_=28follow-up_to_d615eb7bce33=2C_=2312218=29?= Message-ID: http://hg.python.org/cpython/rev/c12401a83a13 changeset: 70761:c12401a83a13 user: ?ric Araujo date: Fri Jun 10 03:48:04 2011 +0200 summary: Remove *.egg-info from Makefile.pre.in (follow-up to d615eb7bce33, #12218) files: Makefile.pre.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -950,7 +950,7 @@ else true; \ fi; \ done - @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.egg-info $(srcdir)/Lib/*.cfg ; \ + @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.cfg ; \ do \ if test -x $$i; then \ $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:06 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_omission_in_test_for_pa?= =?utf8?q?ckaging_install=5Fdistinfo_command=2E?= Message-ID: http://hg.python.org/cpython/rev/9041520be581 changeset: 70762:9041520be581 user: ?ric Araujo date: Fri Jun 10 03:53:49 2011 +0200 summary: Fix omission in test for packaging install_distinfo command. The code does not write checksum or file length for .pyc and .pyo in the RECORD file, in compliance with PEP 376, but the test forgot to take .pyo into account. This was not caught because there were no .pyo in the checkout, but after installing there are .pyo files created by compileall, and the test picks them up. files: Lib/packaging/tests/test_command_install_distinfo.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_command_install_distinfo.py b/Lib/packaging/tests/test_command_install_distinfo.py --- a/Lib/packaging/tests/test_command_install_distinfo.py +++ b/Lib/packaging/tests/test_command_install_distinfo.py @@ -162,7 +162,7 @@ expected = [] for f in install.get_outputs(): - if (f.endswith('.pyc') or f == os.path.join( + if (f.endswith(('.pyc', '.pyo')) or f == os.path.join( install_dir, 'foo-1.0.dist-info', 'RECORD')): expected.append([f, '', '']) else: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:07 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:07 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Clean_up_extra_environment_?= =?utf8?q?variable_after_packaging_tests=2E?= Message-ID: http://hg.python.org/cpython/rev/cb4ea696951e changeset: 70763:cb4ea696951e user: ?ric Araujo date: Fri Jun 10 04:29:43 2011 +0200 summary: Clean up extra environment variable after packaging tests. packaging.util.check_environ will define HOME and PLAT if they don?t exist; for some reason, it does not define PLAT when running the tests from a checkout (so no regrtest warning) but does when running from an installed Python. Cleaning up the envvar in test_dist fixes the warning on my machine, but I suspect that a test runner using a different order to run files or running them in parallel may have PLAT defined in its environment because of another test. Quite a lot of code ends up calling check_environ; maybe we should just clean up PLAT in every test. For now I?m doing this simple fix, we?ll see if we get bug reports. files: Lib/packaging/tests/test_dist.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -35,7 +35,7 @@ support.EnvironRestorer, unittest.TestCase): - restore_environ = ['HOME'] + restore_environ = ['HOME', 'PLAT'] def setUp(self): super(DistributionTestCase, self).setUp() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:08 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Don=E2=80=99t_try_to_instal?= =?utf8?q?l_something_when_running_from_uninstalled_source_=28=2312246=29?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/ff58eec3336b changeset: 70764:ff58eec3336b user: ?ric Araujo date: Fri Jun 10 18:31:40 2011 +0200 summary: Don?t try to install something when running from uninstalled source (#12246). Original patch by Tshepang Lekhonkhobe. files: Lib/packaging/install.py | 17 ++++++++++++++--- Lib/packaging/tests/test_install.py | 14 ++++++++++++-- Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -13,7 +13,7 @@ import shutil import logging import tempfile -from sysconfig import get_config_var, get_path +from sysconfig import get_config_var, get_path, is_python_build from packaging import logger from packaging.dist import Distribution @@ -488,20 +488,31 @@ Returns True on success, False on failure """ + if is_python_build(): + # Python would try to install into the site-packages directory under + # $PREFIX, but when running from an uninstalled code checkout we don't + # want to create directories under the installation root + message = ('installing third-party projects from an uninstalled ' + 'Python is not supported') + logger.error(message) + return False + logger.info('Checking the installation location...') purelib_path = get_path('purelib') + # trying to write a file there try: with tempfile.NamedTemporaryFile(suffix=project, dir=purelib_path) as testfile: testfile.write(b'test') except OSError: - # was unable to write a file + # FIXME this should check the errno, or be removed altogether (race + # condition: the directory permissions could be changed between here + # and the actual install) logger.info('Unable to write in "%s". Do you have the permissions ?' % purelib_path) return False - logger.info('Getting information about %r...', project) try: info = get_infos(project) diff --git a/Lib/packaging/tests/test_install.py b/Lib/packaging/tests/test_install.py --- a/Lib/packaging/tests/test_install.py +++ b/Lib/packaging/tests/test_install.py @@ -1,5 +1,7 @@ """Tests for the packaging.install module.""" import os +import logging +from sysconfig import is_python_build from tempfile import mkstemp from packaging import install @@ -357,9 +359,17 @@ install._install_dist = old_install_dist def test_install_permission_denied(self): - # if we don't have the access to the installation - # path, we should abort immediatly + # if we don't have access to the installation path, we should abort + # immediately project = os.path.join(os.path.dirname(__file__), 'package.tgz') + + # when running from an uninstalled build, a warning is emitted and the + # installation is not attempted + if is_python_build(): + self.assertFalse(install.install(project)) + self.assertEqual(1, len(self.get_logs(logging.ERROR))) + return + install_path = self.mkdtemp() old_get_path = install.get_path install.get_path = lambda path: install_path diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -550,6 +550,7 @@ Robert Lehmann Petri Lehtinen Luke Kenneth Casson Leighton +Tshepang Lekhonkhobe Marc-Andre Lemburg John Lenton Christopher Tur Lesniewski-Laas diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,10 @@ Library ------- +- Issue #12246: Warn and fail when trying to install a third-party project from + an uninstalled Python (built in a source checkout). Original patch by + Tshepang Lekhonkhobe. + - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes instead of os.stat. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 18:35:08 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 10 Jun 2011 18:35:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/11b5d98feb05 changeset: 70765:11b5d98feb05 parent: 70759:f89b42c35ceb parent: 70764:ff58eec3336b user: ?ric Araujo date: Fri Jun 10 18:34:45 2011 +0200 summary: Branch merge files: Lib/packaging/install.py | 19 +++++++-- Lib/packaging/tests/test_command_install_distinfo.py | 2 +- Lib/packaging/tests/test_dist.py | 2 +- Lib/packaging/tests/test_install.py | 14 ++++++- Makefile.pre.in | 2 +- Misc/ACKS | 1 + Misc/NEWS | 4 ++ 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -13,7 +13,7 @@ import shutil import logging import tempfile -from sysconfig import get_config_var, get_path +from sysconfig import get_config_var, get_path, is_python_build from packaging import logger from packaging.dist import Distribution @@ -488,20 +488,31 @@ Returns True on success, False on failure """ + if is_python_build(): + # Python would try to install into the site-packages directory under + # $PREFIX, but when running from an uninstalled code checkout we don't + # want to create directories under the installation root + message = ('installing third-party projects from an uninstalled ' + 'Python is not supported') + logger.error(message) + return False + logger.info('Checking the installation location...') purelib_path = get_path('purelib') + # trying to write a file there try: with tempfile.NamedTemporaryFile(suffix=project, dir=purelib_path) as testfile: testfile.write(b'test') except OSError: - # was unable to write a file + # FIXME this should check the errno, or be removed altogether (race + # condition: the directory permissions could be changed between here + # and the actual install) logger.info('Unable to write in "%s". Do you have the permissions ?' % purelib_path) return False - logger.info('Getting information about %r...', project) try: info = get_infos(project) @@ -520,7 +531,7 @@ except InstallationConflict as e: if logger.isEnabledFor(logging.INFO): - projects = ['%s %s' % (p.name, p.version) for p in e.args[0]] + projects = ['%r %s' % (p.name, p.version) for p in e.args[0]] logger.info('%r conflicts with %s', project, ','.join(projects)) return True diff --git a/Lib/packaging/tests/test_command_install_distinfo.py b/Lib/packaging/tests/test_command_install_distinfo.py --- a/Lib/packaging/tests/test_command_install_distinfo.py +++ b/Lib/packaging/tests/test_command_install_distinfo.py @@ -162,7 +162,7 @@ expected = [] for f in install.get_outputs(): - if (f.endswith('.pyc') or f == os.path.join( + if (f.endswith(('.pyc', '.pyo')) or f == os.path.join( install_dir, 'foo-1.0.dist-info', 'RECORD')): expected.append([f, '', '']) else: diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -35,7 +35,7 @@ support.EnvironRestorer, unittest.TestCase): - restore_environ = ['HOME'] + restore_environ = ['HOME', 'PLAT'] def setUp(self): super(DistributionTestCase, self).setUp() diff --git a/Lib/packaging/tests/test_install.py b/Lib/packaging/tests/test_install.py --- a/Lib/packaging/tests/test_install.py +++ b/Lib/packaging/tests/test_install.py @@ -1,5 +1,7 @@ """Tests for the packaging.install module.""" import os +import logging +from sysconfig import is_python_build from tempfile import mkstemp from packaging import install @@ -357,9 +359,17 @@ install._install_dist = old_install_dist def test_install_permission_denied(self): - # if we don't have the access to the installation - # path, we should abort immediatly + # if we don't have access to the installation path, we should abort + # immediately project = os.path.join(os.path.dirname(__file__), 'package.tgz') + + # when running from an uninstalled build, a warning is emitted and the + # installation is not attempted + if is_python_build(): + self.assertFalse(install.install(project)) + self.assertEqual(1, len(self.get_logs(logging.ERROR))) + return + install_path = self.mkdtemp() old_get_path = install.get_path install.get_path = lambda path: install_path diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -950,7 +950,7 @@ else true; \ fi; \ done - @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.egg-info $(srcdir)/Lib/*.cfg ; \ + @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.cfg ; \ do \ if test -x $$i; then \ $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \ diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -550,6 +550,7 @@ Robert Lehmann Petri Lehtinen Luke Kenneth Casson Leighton +Tshepang Lekhonkhobe Marc-Andre Lemburg John Lenton Christopher Tur Lesniewski-Laas diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,10 @@ Library ------- +- Issue #12246: Warn and fail when trying to install a third-party project from + an uninstalled Python (built in a source checkout). Original patch by + Tshepang Lekhonkhobe. + - Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:42 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_fix_regression_?= =?utf8?q?in_netrc_comment_handling_=28closes_=2312009=29?= Message-ID: http://hg.python.org/cpython/rev/cb3a77b0f8dd changeset: 70766:cb3a77b0f8dd branch: 2.7 parent: 70649:9562cbf41b81 user: Benjamin Peterson date: Fri Jun 10 11:32:52 2011 -0500 summary: fix regression in netrc comment handling (closes #12009) files: Lib/netrc.py | 12 +- Lib/test/test_netrc.py | 133 ++++++++++++++++++++-------- Misc/ACKS | 1 + Misc/NEWS | 5 + 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -41,8 +41,12 @@ if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + # seek to beginning of comment, in case reading the token put + # us on a new line, and then skip the rest of the line. + pos = len(tt) + 1 + lexer.instream.seek(-pos, 1) + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +72,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import test_support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = test_support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp (self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - - def tearDown (self): + def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): test_support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -566,6 +566,7 @@ Derek Morr James A Morrison Pablo Mouzo +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7,6 +7,11 @@ *Release date: 2011-06-XX* +Library +------- + +- Issue #12009: Fixed regression in netrc file comment handling. + Extension Modules ----------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:43 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:43 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_2=2E7=2E2_release_branch_with_fix_for_=2312009?= Message-ID: http://hg.python.org/cpython/rev/6993910be426 changeset: 70767:6993910be426 branch: 2.7 parent: 70661:6e7a98cfcfab parent: 70766:cb3a77b0f8dd user: Benjamin Peterson date: Fri Jun 10 11:33:41 2011 -0500 summary: merge 2.7.2 release branch with fix for #12009 files: Lib/netrc.py | 12 +- Lib/test/test_netrc.py | 133 ++++++++++++++++++++-------- Misc/ACKS | 1 + Misc/NEWS | 5 + 4 files changed, 107 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -41,8 +41,12 @@ if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + # seek to beginning of comment, in case reading the token put + # us on a new line, and then skip the rest of the line. + pos = len(tt) + 1 + lexer.instream.seek(-pos, 1) + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +72,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import test_support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = test_support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp (self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - - def tearDown (self): + def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): test_support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -566,6 +566,7 @@ Derek Morr James A Morrison Pablo Mouzo +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -44,6 +44,11 @@ *Release date: 2011-06-XX* +Library +------- + +- Issue #12009: Fixed regression in netrc file comment handling. + Extension Modules ----------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:44 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:44 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/73918d0c0bf2 changeset: 70768:73918d0c0bf2 branch: 2.7 parent: 70767:6993910be426 parent: 70752:3bb5400f5bea user: Benjamin Peterson date: Fri Jun 10 11:33:58 2011 -0500 summary: merge heads files: Doc/c-api/intro.rst | 4 +- Doc/distutils/introduction.rst | 10 ++++- Doc/install/index.rst | 15 +++++--- Doc/license.rst | 4 +- Doc/reference/datamodel.rst | 2 +- Doc/using/cmdline.rst | 2 +- Lib/ntpath.py | 10 +++++ Lib/test/test_zipfile.py | 18 ++++++++++ Lib/zipfile.py | 16 +++----- Misc/NEWS | 5 ++ Modules/posixmodule.c | 39 ++++++++++++++++++++++ 11 files changed, 102 insertions(+), 23 deletions(-) diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -594,8 +594,8 @@ Compiling the interpreter with the :cmacro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :cmacro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :cmacro:`_DEBUG` macro. When :cmacro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -889,7 +889,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -918,7 +918,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2308,7 +2308,7 @@ * - In ``x * y``, if one operator is a sequence that implements sequence + In ``x * y``, if one operand is a sequence that implements sequence repetition, and the other is an integer (:class:`int` or :class:`long`), sequence repetition is invoked. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -569,7 +569,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -521,3 +521,13 @@ if not rel_list: return curdir return join(*rel_list) + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir as isdir +except ImportError: + # Use genericpath.isdir as imported above. + pass diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -335,6 +335,24 @@ with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -236,16 +236,14 @@ # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,11 @@ Library ------- +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Issue #12080: Fix a performance issue in Decimal._power_exact that caused some corner-case Decimal.__pow__ calls to take an unreasonably long time. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4199,6 +4199,44 @@ CloseHandle(handle); return result; } + +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "et:_isdir", + Py_FileSystemDefaultEncoding, &path)) + return NULL; + + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ #ifdef HAVE_PLOCK @@ -8968,6 +9006,7 @@ {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:44 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_fix_regression_?= =?utf8?q?in_netrc_comment_handling_=28closes_=2312009=29?= Message-ID: http://hg.python.org/cpython/rev/8625ce7da152 changeset: 70769:8625ce7da152 branch: 3.1 parent: 70757:33b7428e65b4 user: Benjamin Peterson date: Fri Jun 10 11:32:52 2011 -0500 summary: fix regression in netrc comment handling (closes #12009) files: Lib/netrc.py | 12 +- Lib/test/test_netrc.py | 131 ++++++++++++++++++++-------- Misc/ACKS | 1 + Misc/NEWS | 5 + 4 files changed, 105 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex +import io, os, shlex __all__ = ["netrc", "NetrcParseError"] @@ -37,12 +37,14 @@ lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword + saved_lineno = lexer.lineno toplevel = tt = lexer.get_token() if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + if lexer.lineno == saved_lineno and len(tt) == 1: + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +70,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp(self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -564,6 +564,7 @@ Derek Morr James A Morrison Mher Movsisyan +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7,6 +7,11 @@ *Release date: 2011-05-XX* +Library +------- + +- Issue #12009: Fixed regression in netrc file comment handling. + Extension Modules ----------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:45 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:45 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1_=28=2312009=29?= Message-ID: http://hg.python.org/cpython/rev/6b93cbb69e49 changeset: 70770:6b93cbb69e49 branch: 3.2 parent: 70758:69c212deb969 parent: 70769:8625ce7da152 user: Benjamin Peterson date: Fri Jun 10 12:29:40 2011 -0500 summary: merge 3.1 (#12009) files: Lib/netrc.py | 12 +- Lib/test/test_netrc.py | 131 ++++++++++++++++++++-------- Misc/ACKS | 1 + Misc/NEWS | 2 + 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex +import io, os, shlex __all__ = ["netrc", "NetrcParseError"] @@ -37,12 +37,14 @@ lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword + saved_lineno = lexer.lineno toplevel = tt = lexer.get_token() if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + if lexer.lineno == saved_lineno and len(tt) == 1: + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +70,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp(self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -609,6 +609,7 @@ James A Morrison Pablo Mouzo Mher Movsisyan +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,8 @@ Library ------- +- Issue #12009: Fixed regression in netrc file comment handling. + - Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:46 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiBtZXJnZSAzLjIgKCMxMjAwOSk=?= Message-ID: http://hg.python.org/cpython/rev/734831b62549 changeset: 70771:734831b62549 parent: 70759:f89b42c35ceb parent: 70770:6b93cbb69e49 user: Benjamin Peterson date: Fri Jun 10 12:30:16 2011 -0500 summary: merge 3.2 (#12009) files: Lib/netrc.py | 12 +- Lib/test/test_netrc.py | 131 ++++++++++++++++++++-------- Misc/ACKS | 1 + Misc/NEWS | 2 + 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex +import io, os, shlex __all__ = ["netrc", "NetrcParseError"] @@ -37,12 +37,14 @@ lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword + saved_lineno = lexer.lineno toplevel = tt = lexer.get_token() if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + if lexer.lineno == saved_lineno and len(tt) == 1: + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +70,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp(self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): support.run_unittest(NetrcTestCase) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -644,6 +644,7 @@ Derek McTavish Mounce Pablo Mouzo Mher Movsisyan +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,8 @@ Library ------- +- Issue #12009: Fixed regression in netrc file comment handling. + - Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:31:47 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 10 Jun 2011 19:31:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/c8bfbad3cf5f changeset: 70772:c8bfbad3cf5f parent: 70771:734831b62549 parent: 70765:11b5d98feb05 user: Benjamin Peterson date: Fri Jun 10 12:32:07 2011 -0500 summary: merge heads files: Lib/packaging/install.py | 19 +++++++-- Lib/packaging/tests/test_command_install_distinfo.py | 2 +- Lib/packaging/tests/test_dist.py | 2 +- Lib/packaging/tests/test_install.py | 14 ++++++- Makefile.pre.in | 2 +- Misc/ACKS | 1 + Misc/NEWS | 4 ++ 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -13,7 +13,7 @@ import shutil import logging import tempfile -from sysconfig import get_config_var, get_path +from sysconfig import get_config_var, get_path, is_python_build from packaging import logger from packaging.dist import Distribution @@ -488,20 +488,31 @@ Returns True on success, False on failure """ + if is_python_build(): + # Python would try to install into the site-packages directory under + # $PREFIX, but when running from an uninstalled code checkout we don't + # want to create directories under the installation root + message = ('installing third-party projects from an uninstalled ' + 'Python is not supported') + logger.error(message) + return False + logger.info('Checking the installation location...') purelib_path = get_path('purelib') + # trying to write a file there try: with tempfile.NamedTemporaryFile(suffix=project, dir=purelib_path) as testfile: testfile.write(b'test') except OSError: - # was unable to write a file + # FIXME this should check the errno, or be removed altogether (race + # condition: the directory permissions could be changed between here + # and the actual install) logger.info('Unable to write in "%s". Do you have the permissions ?' % purelib_path) return False - logger.info('Getting information about %r...', project) try: info = get_infos(project) @@ -520,7 +531,7 @@ except InstallationConflict as e: if logger.isEnabledFor(logging.INFO): - projects = ['%s %s' % (p.name, p.version) for p in e.args[0]] + projects = ['%r %s' % (p.name, p.version) for p in e.args[0]] logger.info('%r conflicts with %s', project, ','.join(projects)) return True diff --git a/Lib/packaging/tests/test_command_install_distinfo.py b/Lib/packaging/tests/test_command_install_distinfo.py --- a/Lib/packaging/tests/test_command_install_distinfo.py +++ b/Lib/packaging/tests/test_command_install_distinfo.py @@ -162,7 +162,7 @@ expected = [] for f in install.get_outputs(): - if (f.endswith('.pyc') or f == os.path.join( + if (f.endswith(('.pyc', '.pyo')) or f == os.path.join( install_dir, 'foo-1.0.dist-info', 'RECORD')): expected.append([f, '', '']) else: diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -35,7 +35,7 @@ support.EnvironRestorer, unittest.TestCase): - restore_environ = ['HOME'] + restore_environ = ['HOME', 'PLAT'] def setUp(self): super(DistributionTestCase, self).setUp() diff --git a/Lib/packaging/tests/test_install.py b/Lib/packaging/tests/test_install.py --- a/Lib/packaging/tests/test_install.py +++ b/Lib/packaging/tests/test_install.py @@ -1,5 +1,7 @@ """Tests for the packaging.install module.""" import os +import logging +from sysconfig import is_python_build from tempfile import mkstemp from packaging import install @@ -357,9 +359,17 @@ install._install_dist = old_install_dist def test_install_permission_denied(self): - # if we don't have the access to the installation - # path, we should abort immediatly + # if we don't have access to the installation path, we should abort + # immediately project = os.path.join(os.path.dirname(__file__), 'package.tgz') + + # when running from an uninstalled build, a warning is emitted and the + # installation is not attempted + if is_python_build(): + self.assertFalse(install.install(project)) + self.assertEqual(1, len(self.get_logs(logging.ERROR))) + return + install_path = self.mkdtemp() old_get_path = install.get_path install.get_path = lambda path: install_path diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -950,7 +950,7 @@ else true; \ fi; \ done - @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.egg-info $(srcdir)/Lib/*.cfg ; \ + @for i in $(srcdir)/Lib/*.py $(srcdir)/Lib/*.cfg ; \ do \ if test -x $$i; then \ $(INSTALL_SCRIPT) $$i $(DESTDIR)$(LIBDEST); \ diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -550,6 +550,7 @@ Robert Lehmann Petri Lehtinen Luke Kenneth Casson Leighton +Tshepang Lekhonkhobe Marc-Andre Lemburg John Lenton Christopher Tur Lesniewski-Laas diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -189,6 +189,10 @@ - Issue #12009: Fixed regression in netrc file comment handling. +- Issue #12246: Warn and fail when trying to install a third-party project from + an uninstalled Python (built in a source checkout). Original patch by + Tshepang Lekhonkhobe. + - Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:54:26 2011 From: python-checkins at python.org (vinay.sajip) Date: Fri, 10 Jun 2011 19:54:26 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Documented_chan?= =?utf8?q?ge_for_Issue_=2312168=2E?= Message-ID: http://hg.python.org/cpython/rev/3cf5d61fd6d7 changeset: 70773:3cf5d61fd6d7 branch: 3.2 parent: 70770:6b93cbb69e49 user: Vinay Sajip date: Fri Jun 10 18:52:50 2011 +0100 summary: Documented change for Issue #12168. files: Doc/library/logging.handlers.rst | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -436,6 +436,21 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is *not* sent to the server. + .. versionchanged:: 3.2.1 + (See: :issue:`12168`.) In earlier versions, the message sent to the + syslog daemons was always terminated with a NUL byte, because early + versions of these daemons expected a NUL terminated message - even + though it's not in the relevant specification (RF 5424). More recent + versions of these daemons don't expect the NUL byte but strip it off + if it's there, and even more recent daemons (which adhere more closely + to RFC 5424) pass the NUL byte on as part of the message. + + To enable easier handling of syslog messages in the face of all these + differing daemon behaviours, the appending of the NUL byte has been + made configurable, through the use of a class-level attribute, + ``append_nul``. This defaults to ``True`` (preserving the existing + behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance + in order for that instance to *not* append the NUL terminator. .. method:: encodePriority(facility, priority) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 19:54:27 2011 From: python-checkins at python.org (vinay.sajip) Date: Fri, 10 Jun 2011 19:54:27 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merged_documentation_change_for_Issue_=2312168=2E?= Message-ID: http://hg.python.org/cpython/rev/6658b9b9f5f3 changeset: 70774:6658b9b9f5f3 parent: 70772:c8bfbad3cf5f parent: 70773:3cf5d61fd6d7 user: Vinay Sajip date: Fri Jun 10 18:54:12 2011 +0100 summary: Merged documentation change for Issue #12168. files: Doc/library/logging.handlers.rst | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -436,6 +436,21 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is *not* sent to the server. + .. versionchanged:: 3.2.1 + (See: :issue:`12168`.) In earlier versions, the message sent to the + syslog daemons was always terminated with a NUL byte, because early + versions of these daemons expected a NUL terminated message - even + though it's not in the relevant specification (RF 5424). More recent + versions of these daemons don't expect the NUL byte but strip it off + if it's there, and even more recent daemons (which adhere more closely + to RFC 5424) pass the NUL byte on as part of the message. + + To enable easier handling of syslog messages in the face of all these + differing daemon behaviours, the appending of the NUL byte has been + made configurable, through the use of a class-level attribute, + ``append_nul``. This defaults to ``True`` (preserving the existing + behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance + in order for that instance to *not* append the NUL terminator. .. method:: encodePriority(facility, priority) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 10 20:05:23 2011 From: python-checkins at python.org (vinay.sajip) Date: Fri, 10 Jun 2011 20:05:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Updated_Formatter=2EformatT?= =?utf8?q?ime_docs_to_indicate_configuration_via_class?= Message-ID: http://hg.python.org/cpython/rev/e572a97a1bd1 changeset: 70775:e572a97a1bd1 user: Vinay Sajip date: Fri Jun 10 19:05:16 2011 +0100 summary: Updated Formatter.formatTime docs to indicate configuration via class attributes. files: Doc/library/logging.rst | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -453,6 +453,18 @@ record. Otherwise, the ISO8601 format is used. The resulting string is returned. + .. versionchanged:: 3.3 + Previously, the default ISO 8601 format was hard-coded as in this + example: ``2010-09-06 22:38:15,292`` where the part before the comma is + handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the + part after the comma is a millisecond value. Because strptime does not + have a format placeholder for milliseconds, the millisecond value is + appended using another format string, ``'%s,%03d'`` ? and both of these + format strings have been hardcoded into this method. With the change, + these strings are defined as class-level attributes which can be + overridden at the instance level when desired. The names of the + attributes are ``default_time_format`` (for the strptime format string) + and ``default_msec_format`` (for appending the millisecond value). .. method:: formatException(exc_info) -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Sat Jun 11 05:10:31 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 11 Jun 2011 05:10:31 +0200 Subject: [Python-checkins] Daily reference leaks (e572a97a1bd1): sum=399 Message-ID: results for e572a97a1bd1 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflog41u2eC', '-x'] From python-checkins at python.org Sat Jun 11 16:52:11 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 16:52:11 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogYnVtcCB0byAyLjcu?= =?utf8?q?2_final?= Message-ID: http://hg.python.org/cpython/rev/3fd7da750b41 changeset: 70776:3fd7da750b41 branch: 2.7 parent: 70766:cb3a77b0f8dd user: Benjamin Peterson date: Sat Jun 11 09:42:44 2011 -0500 summary: bump to 2.7.2 final files: Include/patchlevel.h | 6 +++--- Lib/distutils/__init__.py | 2 +- Lib/idlelib/idlever.py | 2 +- Misc/NEWS | 2 +- Misc/RPM/python-2.7.spec | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,11 +23,11 @@ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 7 #define PY_MICRO_VERSION 2 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.7.2rc1" +#define PY_VERSION "2.7.2" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2rc1" +__version__ = "2.7.2" #--end constants-- diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1,1 +1,1 @@ -IDLE_VERSION = "2.7.2rc1" +IDLE_VERSION = "2.7.2" diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -5,7 +5,7 @@ What's New in Python 2.7.2? =========================== -*Release date: 2011-06-XX* +*Release date: 2011-06-11* Library ------- diff --git a/Misc/RPM/python-2.7.spec b/Misc/RPM/python-2.7.spec --- a/Misc/RPM/python-2.7.spec +++ b/Misc/RPM/python-2.7.spec @@ -39,7 +39,7 @@ %define name python #--start constants-- -%define version 2.7.2rc1 +%define version 2.7.2 %define libvers 2.7 #--end constants-- %define release 1pydotorg -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 16:52:12 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 16:52:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_update_pydoc-to?= =?utf8?q?pics?= Message-ID: http://hg.python.org/cpython/rev/8527427914a2 changeset: 70777:8527427914a2 branch: 2.7 tag: v2.7.2 user: Benjamin Peterson date: Sat Jun 11 09:50:21 2011 -0500 summary: update pydoc-topics files: Lib/pydoc_data/topics.py | 44 ++++++++++++++-------------- 1 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,16 +1,16 @@ -# Autogenerated by Sphinx on Sat Jul 3 08:52:04 2010 +# Autogenerated by Sphinx on Sat Jun 11 09:49:30 2011 topics = {'assert': u'\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets. (This rule is relaxed as of\n Python 1.5; in earlier versions, the object had to be a tuple.\n Since strings are sequences, an assignment like ``a, b = "xy"`` is\n now legal as long as the string has the right length.)\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name. For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``. This transformation is independent of\nthe syntactical context in which the identifier is used. If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen. If the class name\nconsists only of underscores, no transformation is done.\n', 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', + 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush()``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread()`` more\n than once in an effort to acquire as close to *size* bytes as\n possible. Also note that when in non-blocking mode, less data than\n was requested may be returned, even if no *size* parameter was\n given.\n\n Note: This function is simply a wrapper for the underlying ``fread()``\n C function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [5] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets()``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek()``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell()``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets()``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', + 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush()``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread()`` more\n than once in an effort to acquire as close to *size* bytes as\n possible. Also note that when in non-blocking mode, less data than\n was requested may be returned, even if no *size* parameter was\n given.\n\n Note: This function is simply a wrapper for the underlying ``fread()``\n C function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [5] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. When *size* is not\n 0, an empty string is returned *only* when EOF is encountered\n immediately.\n\n Note: Unlike ``stdio``\'s ``fgets()``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek()``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell()``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets()``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with universal newlines enabled (the default)\n this read-only attribute exists, and for files opened in universal\n newline read mode it keeps track of the types of newlines\n encountered while reading the file. The values it can take are\n ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None`` (unknown, no newlines read\n yet) or a tuple containing all the newline types seen, to indicate\n that multiple newline conventions were encountered. For files not\n opened in universal newline read mode the value of this attribute\n will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the ``__nonzero__()`` special method for a way to\nchange this.)\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', @@ -20,39 +20,39 @@ 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n", 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-built-in types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [7]\n', - 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements. Function and class\ndefinitions are also syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print`` statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', + 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements. Function and class\ndefinitions are also syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print`` statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the **with_item**)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'continue': u'\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 2.4: Restarting post-mortem behavior added.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``c`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run_*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\n', + 'debugger': u'\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 2.4: Restarting post-mortem behavior added.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``c`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\n', 'del': u'\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather that spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n', 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', 'else': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). [1] If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use universal newline mode to convert Windows or Mac-style\n newlines.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', 'for': u'\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword. If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument. If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Postive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}.\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{align}{fill}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword. If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument. If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'{\' or \'}\'. The\npresence of a fill character is signaled by the character following\nit, which must be one of the alignment options. If the second\ncharacter of *format_spec* is not a valid alignment option, then it is\nassumed that both the fill character and the alignment option are\nabsent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}.\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n', 'global': u'\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', - 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', 'if': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': u'\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an ``exec`` statement or calls to the built-in\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', + 'import': u'\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an ``exec`` statement or calls to the built-in\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-built-in types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [7]\n', 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', 'lambda': u'\nLambdas\n*******\n\n lambda_form ::= "lambda" [parameter_list]: expression\n old_lambda_form ::= "lambda" [parameter_list]: old_expression\n\nLambda forms (lambda expressions) have the same syntactic position as\nexpressions. They are a shorthand to create anonymous functions; the\nexpression ``lambda arguments: expression`` yields a function object.\nThe unnamed object behaves like a function object defined with\n\n def name(arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda forms cannot contain\nstatements.\n', 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n old_expression ::= or_test | old_lambda_form\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no 's') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", + 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no 's') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change.\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', - 'operator-summary': u'\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``, | Comparisons, including membership |\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | tests and identity tests, |\n| ``==`` | |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key:datum...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. Function\n ``fmod()`` in the ``math`` module returns a result whose sign\n matches the sign of the first argument instead, and so returns\n ``-1e-100`` in this case. Which approach is more appropriate\n depends on the application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', + 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (ex:\nalways close files).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', + 'operator-summary': u'\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``, | Comparisons, including membership |\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | tests and identity tests, |\n| ``==`` | |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [9] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key:datum...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[9] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', 'pass': u'\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is a whitespace character except ``\' \'``, or (3) when the last\nwrite operation on standard output was not a ``print`` statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', @@ -63,21 +63,21 @@ 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept plain or long integers as arguments. The\narguments are converted to a common type. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by ``pow(2, n)``. A\nleft shift by *n* bits is defined as multiplication with ``pow(2,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n\nNote: In the current implementation, the right-hand operand is required to\n be at most ``sys.maxsize``. If the right-hand operand is larger\n than ``sys.maxsize`` an ``OverflowError`` exception is raised.\n', 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', 'specialattrs': u"\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object's\n (writable) attributes.\n\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nThe following attributes are only supported by *new-style class*es.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n Each new-style class keeps a list of weak references to its\n immediate subclasses. This method returns a list of all those\n references still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n\n[5] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nCustomizing instance and subclass checks\n========================================\n\nNew in version 2.6.\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print "Metaclass getattribute invoked"\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object):\n ... __metaclass__ = Meta\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print "Class getattribute invoked"\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', + 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nCustomizing instance and subclass checks\n========================================\n\nNew in version 2.6.\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print "Metaclass getattribute invoked"\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object):\n ... __metaclass__ = Meta\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print "Class getattribute invoked"\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', 'string-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', + 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n | "b" | "B" | "br" | "Br" | "bR" | "BR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. A prefix of ``\'b\'`` or ``\'B\'`` is\nignored in Python 2; it indicates that the literal should become a\nbytes literal in Python 3 (e.g. when code is automatically converted\nwith 2to3). A ``\'u\'`` or ``\'b\'`` prefix may be followed by an ``\'r\'``\nprefix.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object of a sequence or mapping type.\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``x[-1]`` selects the last item of\n``x``.) The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', 'truth': u"\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0L``, ``0.0``,\n ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", 'try': u'\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key is\n specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n\n viewitems()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.viewkeys()``, ``dict.viewvalues()`` and\n``dict.viewitems()`` are *view objects*. They provide a dynamic view\non the dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n', + 'typesmapping': u'\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key is\n specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 1, "two": 2}``:\n\n * ``dict(one=1, two=2)``\n\n * ``dict({\'one\': 1, \'two\': 2})``\n\n * ``dict(zip((\'one\', \'two\'), (1, 2)))``\n\n * ``dict([[\'two\', 2], [\'one\', 1]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n\n viewitems()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.viewkeys()``, ``dict.viewvalues()`` and\n``dict.viewitems()`` are *view objects*. They provide a dynamic view\non the dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n', 'typesmethods': u"\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", 'typesmodules': u"\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n", - 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n', - 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n", + 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``bytearray``, ``buffer``, ``xrange``\n***************************************************************************************************\n\nThere are seven sequence types: strings, Unicode strings, lists,\ntuples, bytearrays, buffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBytearray objects are created with the built-in function\n``bytearray()``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.index(i)`` | index of the first occurence of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.count(i)`` | total number of occurences of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(number)03d quote types.\' % \\\n... {"language": "Python", "number": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n', + 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n", 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', 'while': u'\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', - 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', + 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the **with_item**)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 16:52:13 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 16:52:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Added_tag_v2=2E?= =?utf8?q?7=2E2_for_changeset_8527427914a2?= Message-ID: http://hg.python.org/cpython/rev/eb3c9b74884c changeset: 70778:eb3c9b74884c branch: 2.7 user: Benjamin Peterson date: Sat Jun 11 09:50:36 2011 -0500 summary: Added tag v2.7.2 for changeset 8527427914a2 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -149,3 +149,4 @@ 63d9f00fea0730c1c437a50f64a42b7792bdcbfb v2.7.1rc1 5395f96588d4f0199d329cb79eb109648dc4ef5e v2.7.1 f48756685406e8d0fa9d23d841fceb07e36a5656 v2.7.2rc1 +8527427914a29d895bcb30be76a465143993a793 v2.7.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 16:52:14 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 16:52:14 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_2=2E7=2E2_release_branch?= Message-ID: http://hg.python.org/cpython/rev/31afae5c2a8d changeset: 70779:31afae5c2a8d branch: 2.7 parent: 70768:73918d0c0bf2 parent: 70778:eb3c9b74884c user: Benjamin Peterson date: Sat Jun 11 09:51:21 2011 -0500 summary: merge 2.7.2 release branch files: .hgtags | 1 + Include/patchlevel.h | 6 +- Lib/distutils/__init__.py | 2 +- Lib/idlelib/idlever.py | 2 +- Lib/pydoc_data/topics.py | 44 +++++++++++++------------- Misc/NEWS | 2 +- Misc/RPM/python-2.7.spec | 2 +- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -149,3 +149,4 @@ 63d9f00fea0730c1c437a50f64a42b7792bdcbfb v2.7.1rc1 5395f96588d4f0199d329cb79eb109648dc4ef5e v2.7.1 f48756685406e8d0fa9d23d841fceb07e36a5656 v2.7.2rc1 +8527427914a29d895bcb30be76a465143993a793 v2.7.2 diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,11 +23,11 @@ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 7 #define PY_MICRO_VERSION 2 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.7.2rc1" +#define PY_VERSION "2.7.2" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "2.7.2rc1" +__version__ = "2.7.2" #--end constants-- diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1,1 +1,1 @@ -IDLE_VERSION = "2.7.2rc1" +IDLE_VERSION = "2.7.2" diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,16 +1,16 @@ -# Autogenerated by Sphinx on Sat Jul 3 08:52:04 2010 +# Autogenerated by Sphinx on Sat Jun 11 09:49:30 2011 topics = {'assert': u'\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets. (This rule is relaxed as of\n Python 1.5; in earlier versions, the object had to be a tuple.\n Since strings are sequences, an assignment like ``a, b = "xy"`` is\n now legal as long as the string has the right length.)\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, ``IndexError`` is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to (small) integers. If either\n bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name. For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``. This transformation is independent of\nthe syntactical context in which the identifier is used. If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen. If the class name\nconsists only of underscores, no transformation is done.\n', 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section *Literals* for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', + 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n``AttributeError`` is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer (plain or long) and the other must be a sequence.\nIn the former case, the numbers are converted to a common type and\nthen multiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: ``x == (x/y)*y + (x%y)``. Integer division and\nmodulo are also connected with the built-in function ``divmod()``:\n``divmod(x, y) == (x/y, x%y)``. These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere ``x/y`` is replaced by ``floor(x/y)`` or ``floor(x/y) - 1`` [3].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\n*String Formatting Operations*.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the ``divmod()`` function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``func_code`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec`` statement or the built-in ``eval()``\nfunction.\n\nSee *The standard type hierarchy* for more information.\n', 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see *Slicings*). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed ``Ellipsis`` (a built-in name).\n\nIt is written as ``Ellipsis``.\n', - 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush()``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread()`` more\n than once in an effort to acquire as close to *size* bytes as\n possible. Also note that when in non-blocking mode, less data than\n was requested may be returned, even if no *size* parameter was\n given.\n\n Note: This function is simply a wrapper for the underlying ``fread()``\n C function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [5] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. An empty string is\n returned *only* when EOF is encountered immediately.\n\n Note: Unlike ``stdio``\'s ``fgets()``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek()``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell()``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets()``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with the *--with-universal-newlines* option to\n **configure** (the default) this read-only attribute exists, and\n for files opened in universal newline read mode it keeps track of\n the types of newlines encountered while reading the file. The\n values it can take are ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None``\n (unknown, no newlines read yet) or a tuple containing all the\n newline types seen, to indicate that multiple newline conventions\n were encountered. For files not opened in universal newline read\n mode the value of this attribute will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', + 'bltin-file-objects': u'\nFile Objects\n************\n\nFile objects are implemented using C\'s ``stdio`` package and can be\ncreated with the built-in ``open()`` function. File objects are also\nreturned by some other built-in functions and methods, such as\n``os.popen()`` and ``os.fdopen()`` and the ``makefile()`` method of\nsocket objects. Temporary files can be created using the ``tempfile``\nmodule, and high-level file operations such as copying, moving, and\ndeleting files and directories can be achieved with the ``shutil``\nmodule.\n\nWhen a file operation fails for an I/O-related reason, the exception\n``IOError`` is raised. This includes situations where the operation\nis not defined for some reason, like ``seek()`` on a tty device or\nwriting a file opened for reading.\n\nFiles have the following methods:\n\nfile.close()\n\n Close the file. A closed file cannot be read or written any more.\n Any operation which requires that the file be open will raise a\n ``ValueError`` after the file has been closed. Calling ``close()``\n more than once is allowed.\n\n As of Python 2.5, you can avoid having to call this method\n explicitly if you use the ``with`` statement. For example, the\n following code will automatically close *f* when the ``with`` block\n is exited:\n\n from __future__ import with_statement # This isn\'t required in Python 2.6\n\n with open("hello.txt") as f:\n for line in f:\n print line\n\n In older versions of Python, you would have needed to do this to\n get the same effect:\n\n f = open("hello.txt")\n try:\n for line in f:\n print line\n finally:\n f.close()\n\n Note: Not all "file-like" types in Python support use as a context\n manager for the ``with`` statement. If your code is intended to\n work with any file-like object, you can use the function\n ``contextlib.closing()`` instead of using the object directly.\n\nfile.flush()\n\n Flush the internal buffer, like ``stdio``\'s ``fflush()``. This may\n be a no-op on some file-like objects.\n\n Note: ``flush()`` does not necessarily write the file\'s data to disk.\n Use ``flush()`` followed by ``os.fsync()`` to ensure this\n behavior.\n\nfile.fileno()\n\n Return the integer "file descriptor" that is used by the underlying\n implementation to request I/O operations from the operating system.\n This can be useful for other, lower level interfaces that use file\n descriptors, such as the ``fcntl`` module or ``os.read()`` and\n friends.\n\n Note: File-like objects which do not have a real file descriptor should\n *not* provide this method!\n\nfile.isatty()\n\n Return ``True`` if the file is connected to a tty(-like) device,\n else ``False``.\n\n Note: If a file-like object is not associated with a real file, this\n method should *not* be implemented.\n\nfile.next()\n\n A file object is its own iterator, for example ``iter(f)`` returns\n *f* (unless *f* is closed). When a file is used as an iterator,\n typically in a ``for`` loop (for example, ``for line in f: print\n line``), the ``next()`` method is called repeatedly. This method\n returns the next input line, or raises ``StopIteration`` when EOF\n is hit when the file is open for reading (behavior is undefined\n when the file is open for writing). In order to make a ``for``\n loop the most efficient way of looping over the lines of a file (a\n very common operation), the ``next()`` method uses a hidden read-\n ahead buffer. As a consequence of using a read-ahead buffer,\n combining ``next()`` with other file methods (like ``readline()``)\n does not work right. However, using ``seek()`` to reposition the\n file to an absolute position will flush the read-ahead buffer.\n\n New in version 2.3.\n\nfile.read([size])\n\n Read at most *size* bytes from the file (less if the read hits EOF\n before obtaining *size* bytes). If the *size* argument is negative\n or omitted, read all data until EOF is reached. The bytes are\n returned as a string object. An empty string is returned when EOF\n is encountered immediately. (For certain files, like ttys, it\n makes sense to continue reading after an EOF is hit.) Note that\n this method may call the underlying C function ``fread()`` more\n than once in an effort to acquire as close to *size* bytes as\n possible. Also note that when in non-blocking mode, less data than\n was requested may be returned, even if no *size* parameter was\n given.\n\n Note: This function is simply a wrapper for the underlying ``fread()``\n C function, and will behave the same in corner cases, such as\n whether the EOF value is cached.\n\nfile.readline([size])\n\n Read one entire line from the file. A trailing newline character\n is kept in the string (but may be absent when a file ends with an\n incomplete line). [5] If the *size* argument is present and non-\n negative, it is a maximum byte count (including the trailing\n newline) and an incomplete line may be returned. When *size* is not\n 0, an empty string is returned *only* when EOF is encountered\n immediately.\n\n Note: Unlike ``stdio``\'s ``fgets()``, the returned string contains null\n characters (``\'\\0\'``) if they occurred in the input.\n\nfile.readlines([sizehint])\n\n Read until EOF using ``readline()`` and return a list containing\n the lines thus read. If the optional *sizehint* argument is\n present, instead of reading up to EOF, whole lines totalling\n approximately *sizehint* bytes (possibly after rounding up to an\n internal buffer size) are read. Objects implementing a file-like\n interface may choose to ignore *sizehint* if it cannot be\n implemented, or cannot be implemented efficiently.\n\nfile.xreadlines()\n\n This method returns the same thing as ``iter(f)``.\n\n New in version 2.1.\n\n Deprecated since version 2.3: Use ``for line in file`` instead.\n\nfile.seek(offset[, whence])\n\n Set the file\'s current position, like ``stdio``\'s ``fseek()``. The\n *whence* argument is optional and defaults to ``os.SEEK_SET`` or\n ``0`` (absolute file positioning); other values are ``os.SEEK_CUR``\n or ``1`` (seek relative to the current position) and\n ``os.SEEK_END`` or ``2`` (seek relative to the file\'s end). There\n is no return value.\n\n For example, ``f.seek(2, os.SEEK_CUR)`` advances the position by\n two and ``f.seek(-3, os.SEEK_END)`` sets the position to the third\n to last.\n\n Note that if the file is opened for appending (mode ``\'a\'`` or\n ``\'a+\'``), any ``seek()`` operations will be undone at the next\n write. If the file is only opened for writing in append mode (mode\n ``\'a\'``), this method is essentially a no-op, but it remains useful\n for files opened in append mode with reading enabled (mode\n ``\'a+\'``). If the file is opened in text mode (without ``\'b\'``),\n only offsets returned by ``tell()`` are legal. Use of other\n offsets causes undefined behavior.\n\n Note that not all file objects are seekable.\n\n Changed in version 2.6: Passing float values as offset has been\n deprecated.\n\nfile.tell()\n\n Return the file\'s current position, like ``stdio``\'s ``ftell()``.\n\n Note: On Windows, ``tell()`` can return illegal values (after an\n ``fgets()``) when reading files with Unix-style line-endings. Use\n binary mode (``\'rb\'``) to circumvent this problem.\n\nfile.truncate([size])\n\n Truncate the file\'s size. If the optional *size* argument is\n present, the file is truncated to (at most) that size. The size\n defaults to the current position. The current file position is not\n changed. Note that if a specified size exceeds the file\'s current\n size, the result is platform-dependent: possibilities include that\n the file may remain unchanged, increase to the specified size as if\n zero-filled, or increase to the specified size with undefined new\n content. Availability: Windows, many Unix variants.\n\nfile.write(str)\n\n Write a string to the file. There is no return value. Due to\n buffering, the string may not actually show up in the file until\n the ``flush()`` or ``close()`` method is called.\n\nfile.writelines(sequence)\n\n Write a sequence of strings to the file. The sequence can be any\n iterable object producing strings, typically a list of strings.\n There is no return value. (The name is intended to match\n ``readlines()``; ``writelines()`` does not add line separators.)\n\nFiles support the iterator protocol. Each iteration returns the same\nresult as ``file.readline()``, and iteration ends when the\n``readline()`` method returns an empty string.\n\nFile objects also offer a number of other interesting attributes.\nThese are not required for file-like objects, but should be\nimplemented if they make sense for the particular object.\n\nfile.closed\n\n bool indicating the current state of the file object. This is a\n read-only attribute; the ``close()`` method changes the value. It\n may not be available on all file-like objects.\n\nfile.encoding\n\n The encoding that this file uses. When Unicode strings are written\n to a file, they will be converted to byte strings using this\n encoding. In addition, when the file is connected to a terminal,\n the attribute gives the encoding that the terminal is likely to use\n (that information might be incorrect if the user has misconfigured\n the terminal). The attribute is read-only and may not be present\n on all file-like objects. It may also be ``None``, in which case\n the file uses the system default encoding for converting Unicode\n strings.\n\n New in version 2.3.\n\nfile.errors\n\n The Unicode error handler used along with the encoding.\n\n New in version 2.6.\n\nfile.mode\n\n The I/O mode for the file. If the file was created using the\n ``open()`` built-in function, this will be the value of the *mode*\n parameter. This is a read-only attribute and may not be present on\n all file-like objects.\n\nfile.name\n\n If the file object was created using ``open()``, the name of the\n file. Otherwise, some string that indicates the source of the file\n object, of the form ``<...>``. This is a read-only attribute and\n may not be present on all file-like objects.\n\nfile.newlines\n\n If Python was built with universal newlines enabled (the default)\n this read-only attribute exists, and for files opened in universal\n newline read mode it keeps track of the types of newlines\n encountered while reading the file. The values it can take are\n ``\'\\r\'``, ``\'\\n\'``, ``\'\\r\\n\'``, ``None`` (unknown, no newlines read\n yet) or a tuple containing all the newline types seen, to indicate\n that multiple newline conventions were encountered. For files not\n opened in universal newline read mode the value of this attribute\n will be ``None``.\n\nfile.softspace\n\n Boolean that indicates whether a space character needs to be\n printed before another value when using the ``print`` statement.\n Classes that are trying to simulate a file object should also have\n a writable ``softspace`` attribute, which should be initialized to\n zero. This will be automatic for most classes implemented in\n Python (care may be needed for objects that override attribute\n access); types implemented in C will have to provide a writable\n ``softspace`` attribute.\n\n Note: This attribute is not used to control the ``print`` statement,\n but to allow the implementation of ``print`` to keep track of its\n internal state.\n', 'bltin-null-object': u"\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name).\n\nIt is written as ``None``.\n", 'bltin-type-objects': u"\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the ``__nonzero__()`` special method for a way to\nchange this.)\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', @@ -20,39 +20,39 @@ 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', 'coercion-rules': u"\nCoercion rules\n**************\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don't define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator '``+``', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base's ``__rop__()`` method, the right operand's ``__rop__()``\n method is tried *before* the left operand's ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand's ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type's ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like '``+=``') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n", 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-built-in types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [7]\n', - 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements. Function and class\ndefinitions are also syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print`` statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', + 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements. Function and class\ndefinitions are also syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print`` statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the **with_item**)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with ``self.name = value``.\nBoth class and instance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'continue': u'\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," the arguments\nare coerced using the coercion rules listed at *Coercion rules*. If\nboth arguments are standard numeric types, the following coercions are\napplied:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 2.4: Restarting post-mortem behavior added.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``c`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run_*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\n', + 'debugger': u'\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 2.4: Restarting post-mortem behavior added.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``c`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type ``continue``, or you can step through the\n statement using ``step`` or ``next`` (all these commands are\n explained below). The optional *globals* and *locals* arguments\n specify the environment in which the code is executed; by default\n the dictionary of the module ``__main__`` is used. (See the\n explanation of the ``exec`` statement or the ``eval()`` built-in\n function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When ``runeval()`` returns, it returns the value of the\n expression. Otherwise this function is similar to ``run()``.\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\n', 'del': u'\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather that spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n', 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', 'else': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exec': u'\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a string, an open file object, or\na code object. If it is a string, the string is parsed as a suite of\nPython statements which is then executed (unless a syntax error\noccurs). [1] If it is an open file, the file is parsed until EOF and\nexecuted. If it is a code object, it is simply executed. In all\ncases, the code that\'s executed is expected to be valid as file input\n(see section *File input*). Be aware that the ``return`` and\n``yield`` statements may not be used outside of function definitions\neven within the context of code passed to the ``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use universal newline mode to convert Windows or Mac-style\n newlines.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', 'for': u'\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword. If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument. If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Postive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}.\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{align}{fill}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword. If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument. If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'{\' or \'}\'. The\npresence of a fill character is signaled by the character following\nit, which must be one of the alignment options. If the second\ncharacter of *format_spec* is not a valid alignment option, then it is\nassumed that both the fill character and the alignment option are\nabsent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}.\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier [, "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n', 'global': u'\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', - 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: ``None`` became a constant and is now\nrecognized by the compiler as a name for the built-in object ``None``.\nAlthough it is not a keyword, you cannot assign a different object to\nit.\n\nChanged in version 2.5: Both ``as`` and ``with`` are only recognized\nwhen the ``with_statement`` future feature has been enabled. It will\nalways be enabled in Python 2.6. See section *The with statement* for\ndetails. Note that using ``as`` and ``with`` as identifiers will\nalways issue a warning, even when the ``with_statement`` future\ndirective is not in effect.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', 'if': u'\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': u'\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an ``exec`` statement or calls to the built-in\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', + 'import': u'\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. If the\nwild card form of import --- ``import *`` --- is used in a function\nand the function contains or is a nested block with free variables,\nthe compiler will raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.6 are ``unicode_literals``,\n``print_function``, ``absolute_import``, ``division``, ``generators``,\n``nested_scopes`` and ``with_statement``. ``generators``,\n``with_statement``, ``nested_scopes`` are redundant in Python version\n2.6 and above because they are always enabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an ``exec`` statement or calls to the built-in\nfunctions ``compile()`` and ``execfile()`` that occur in a module\n``M`` containing a future statement will, by default, use the new\nsyntax or semantics associated with the future statement. This can,\nstarting with Python 2.2 be controlled by optional arguments to\n``compile()`` --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe forms ``<>`` and ``!=`` are equivalent; for consistency with C,\n``!=`` is preferred; where ``!=`` is mentioned below ``<>`` is also\naccepted. The ``<>`` spelling is considered obsolescent.\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nobjects of different types *always* compare unequal, and are ordered\nconsistently but arbitrarily. You can control comparison behavior of\nobjects of non-built-in types by defining a ``__cmp__`` method or rich\ncomparison methods like ``__gt__``, described in section *Special\nmethod names*.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the ``in`` and ``not in``\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n Unicode and 8-bit strings are fully interoperable in this behavior.\n [4]\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``cmp([1,2,x], [1,2,y])`` returns\n the same as ``cmp(x,y)``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nThe operators ``in`` and ``not in`` test for collection membership.\n``x in s`` evaluates to true if *x* is a member of the collection *s*,\nand false otherwise. ``x not in s`` returns the negation of ``x in\ns``. The collection membership test has traditionally been bound to\nsequences; an object is a member of a collection if the collection is\na sequence and contains an element equal to that object. However, it\nmake sense for many other object types to support membership tests\nwithout being a sequence. In particular, dictionaries (for keys) and\nsets support membership testing.\n\nFor the list and tuple types, ``x in y`` is true if and only if there\nexists an index *i* such that ``x == y[i]`` is true.\n\nFor the Unicode and string types, ``x in y`` is true if and only if\n*x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nNote, *x* and *y* need not be the same type; consequently, ``u\'ab\' in\n\'abc\'`` will return ``True``. Empty strings are always considered to\nbe a substring of any other string, so ``"" in "abc"`` will return\n``True``.\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength ``1``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [7]\n', 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case ``\'l\'`` and upper case ``\'L\'`` are allowed as\nsuffix for long integers, it is strongly recommended to always use\n``\'L\'``, since the letter ``\'l\'`` looks too much like the digit\n``\'1\'``.\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', 'lambda': u'\nLambdas\n*******\n\n lambda_form ::= "lambda" [parameter_list]: expression\n old_lambda_form ::= "lambda" [parameter_list]: old_expression\n\nLambda forms (lambda expressions) have the same syntactic position as\nexpressions. They are a shorthand to create anonymous functions; the\nexpression ``lambda arguments: expression`` yields a function object.\nThe unnamed object behaves like a function object defined with\n\n def name(arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda forms cannot contain\nstatements.\n', 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n old_expression ::= or_test | old_lambda_form\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one ``for`` clause and zero or\nmore ``for`` or ``if`` clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the\n``for`` or ``if`` clauses a block, nesting from left to right, and\nevaluating the expression to produce a list element each time the\ninnermost block is reached [1].\n', - 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no 's') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", + 'naming': u"\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no 's'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no 's') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n", 'numbers': u"\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n', - 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change.\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', - 'operator-summary': u'\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``, | Comparisons, including membership |\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | tests and identity tests, |\n| ``==`` | |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key:datum...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. Function\n ``fmod()`` in the ``math`` module returns a result whose sign\n matches the sign of the first argument instead, and so returns\n ``-1e-100`` in this case. Which approach is more appropriate\n depends on the application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', + 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (ex:\nalways close files).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement provides a convenient way to do\nthis.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', + 'operator-summary': u'\nSummary\n*******\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` *x* | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not`` ``in``, ``is``, ``is not``, | Comparisons, including membership |\n| ``<``, ``<=``, ``>``, ``>=``, ``<>``, ``!=``, | tests and identity tests, |\n| ``==`` | |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [9] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key:datum...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.0\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[9] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', 'pass': u'\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', 'print': u'\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is a whitespace character except ``\' \'``, or (3) when the last\nwrite operation on standard output was not a ``print`` statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', @@ -63,21 +63,21 @@ 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept plain or long integers as arguments. The\narguments are converted to a common type. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by ``pow(2, n)``. A\nleft shift by *n* bits is defined as multiplication with ``pow(2,\nn)``. Negative shift counts raise a ``ValueError`` exception.\n\nNote: In the current implementation, the right-hand operand is required to\n be at most ``sys.maxsize``. If the right-hand operand is larger\n than ``sys.maxsize`` an ``OverflowError`` exception is raised.\n', 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n``sys.maxint``, respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that ``i <= k < j`` where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of an ellipsis slice\nitem is the built-in ``Ellipsis`` object. The conversion of a proper\nslice is a slice object (see section *The standard type hierarchy*)\nwhose ``start``, ``stop`` and ``step`` attributes are the values of\nthe expressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', 'specialattrs': u"\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object's\n (writable) attributes.\n\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function ``dir()``\n to get a list of an object's attributes. This attribute is no\n longer available.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nThe following attributes are only supported by *new-style class*es.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n Each new-style class keeps a list of weak references to its\n immediate subclasses. This method returns a list of all those\n references still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n\n[5] The advantage of leaving the newline on is that returning an empty\n string is then an unambiguous EOF indication. It is also possible\n (in cases where it might matter, for example, if you want to make\n an exact copy of a file while scanning its lines) to tell whether\n the last line of a file ended in a newline or not (yes this\n happens!).\n", - 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another new-style class, known as the *owner*\nclass. In the examples below, "the attribute" refers to the attribute\nwhose name is the key of the property in the owner class\'\n``__dict__``. Descriptors can only be implemented as new-style\nclasses themselves.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nCustomizing instance and subclass checks\n========================================\n\nNew in version 2.6.\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print "Metaclass getattribute invoked"\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object):\n ... __metaclass__ = Meta\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print "Class getattribute invoked"\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', + 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``x.__getitem__(i)`` for\nold-style classes and ``type(x).__getitem__(x, i)`` for new-style\nclasses. Except where mentioned, attempts to execute an operation\nraise an exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_traceback`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.exc_traceback`` or ``sys.last_traceback``. Circular\n references which are garbage are detected when the option cycle\n detector is enabled (it\'s on by default), but can only be cleaned\n up if there are no Python-level ``__del__()`` methods involved.\n Refer to the documentation for the ``gc`` module for more\n information about how ``__del__()`` methods are handled by the\n cycle detector, particularly the description of the ``garbage``\n value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function and by string\n conversions (reverse quotes) to compute the "official" string\n representation of an object. If at all possible, this should look\n like a valid Python expression that could be used to recreate an\n object with the same value (given an appropriate environment). If\n this is not possible, a string of the form ``<...some useful\n description...>`` should be returned. The return value must be a\n string object. If a class defines ``__repr__()`` but not\n ``__str__()``, then ``__repr__()`` is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print``\n statement to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to ``__cmp__()`` below. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` call ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and\n ``x>=y`` calls ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if ``self < other``,\n zero if ``self == other``, a positive integer if ``self > other``.\n If no ``__cmp__()``, ``__eq__()`` or ``__ne__()`` operation is\n defined, class instances are compared by object identity\n ("address"). See also the description of ``__hash__()`` for some\n important notes on creating *hashable* objects which support custom\n comparison operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by ``__cmp__()`` has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define a ``__cmp__()`` or ``__eq__()`` method\n it should not define a ``__hash__()`` operation either; if it\n defines ``__cmp__()`` or ``__eq__()`` but not ``__hash__()``, its\n instances will not be usable in hashed collections. If a class\n defines mutable objects and implements a ``__cmp__()`` or\n ``__eq__()`` method, it should not implement ``__hash__()``, since\n hashable collection implementations require that a object\'s hash\n value is immutable (if the object\'s hash value changes, it will be\n in the wrong hash bucket).\n\n User-defined classes have ``__cmp__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__cmp__()`` or ``__eq__()`` such that\n the hash value returned is no longer appropriate (e.g. by switching\n to a value-based concept of equality instead of the default\n identity based equality) can explicitly flag themselves as being\n unhashable by setting ``__hash__ = None`` in the class definition.\n Doing so means that not only will instances of the class raise an\n appropriate ``TypeError`` when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking ``isinstance(obj, collections.Hashable)``\n (unlike classes which define their own ``__hash__()`` to explicitly\n raise ``TypeError``).\n\n Changed in version 2.5: ``__hash__()`` may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: ``__hash__`` may now be set to ``None`` to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``, or their integer\n equivalents ``0`` or ``1``. When this method is not defined,\n ``__len__()`` is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither ``__len__()`` nor ``__nonzero__()``, all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement ``unicode()`` built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should not simply execute ``self.name = value`` --- this would\n cause a recursive call to itself. Instead, it should insert the\n value in the dictionary of instance attributes, e.g.,\n ``self.__dict__[name] = value``. For new-style classes, rather\n than accessing the instance dictionary, it should call the base\n class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup for new-style\n classes*.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass ``object()`` or\n``type()``).\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to a new-style object instance, ``a.x`` is transformed\n into the call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a new-style class, ``A.x`` is transformed into the\n call: ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding ``\'__dict__\'`` to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n Changed in version 2.3: Previously, adding ``\'__weakref__\'`` to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``long``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using ``type()``. A\nclass definition is read into a separate namespace and the value of\nclass name is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of ``type()``. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for ``name``,\n ``bases``, and ``dict``. Upon class creation, the callable is used\n instead of the built-in ``type()``.\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If ``dict[\'__metaclass__\']`` exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nCustomizing instance and subclass checks\n========================================\n\nNew in version 2.6.\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python\'s\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine ``__getslice__()``; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the ``__getitem__()`` method. (However, built-in types in\n CPython currently still implement ``__getslice__()``. Therefore,\n you have to override it in derived classes when implementing\n slicing.)\n\n Called to implement evaluation of ``self[i:j]``. The returned\n object should be of the same type as *self*. Note that missing *i*\n or *j* in the slice expression are replaced by zero or\n ``sys.maxint``, respectively. If negative indexes are used in the\n slice, the length of the sequence is added to that index. If the\n instance does not implement the ``__len__()`` method, an\n ``AttributeError`` is raised. No guarantee is made that indexes\n adjusted this way are not still negative. Indexes which are\n greater than the length of the sequence are not modified. If no\n ``__getslice__()`` is found, a slice object is created instead, and\n passed to ``__getitem__()`` instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``.\n\n This method is deprecated. If no ``__setslice__()`` is found, or\n for extended slicing of the form ``self[i:j:k]``, a slice object is\n created, and passed to ``__setitem__()``, instead of\n ``__setslice__()`` being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of ``self[i:j]``. Same notes for *i*\n and *j* as for ``__getslice__()``. This method is deprecated. If no\n ``__delslice__()`` is found, or for extended slicing of the form\n ``self[i:j:k]``, a slice object is created, and passed to\n ``__delitem__()``, instead of ``__delslice__()`` being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, ``__getitem__()``, ``__setitem__()`` or\n``__delitem__()`` is called with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n``__getitem__()``, ``__setitem__()`` and ``__delitem__()`` support\nslice objects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to ``max()``; these are necessary because of the\nhandling of negative indices before the ``__*slice__()`` methods are\ncalled. When negative indexes are used, the ``__*item__()`` methods\nreceive them as provided, but the ``__*slice__()`` methods get a\n"cooked" form of the index values. For each negative index value, the\nlength of the sequence is added to the index before calling the method\n(which may still result in a negative index); this is the customary\nhandling of negative indexes by the built-in sequence types, and the\n``__*item__()`` methods are expected to do this as well. However,\nsince they should already be doing that, negative indexes cannot be\npassed in; they must be constrained to the bounds of the sequence\nbefore being passed to the ``__*item__()`` methods. Calling ``max(0,\ni)`` conveniently returns the proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``//``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For\n instance, to evaluate the expression ``x + y``, where *x* is an\n instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()`` (described below). Note\n that ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator (``/``) is implemented by these methods. The\n ``__truediv__()`` method is used when ``__future__.division`` is in\n effect, otherwise ``__div__()`` is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; ``TypeError`` will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``%``, ``divmod()``,\n ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with\n reflected (swapped) operands. These functions are only called if\n the left operand does not support the corresponding operation and\n the operands are of different types. [2] For instance, to evaluate\n the expression ``x - y``, where *y* is an instance of a class that\n has an ``__rsub__()`` method, ``y.__rsub__(x)`` is called if\n ``x.__sub__(y)`` returns *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``long()``, and ``float()``. Should return a value of\n the appropriate type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions ``oct()`` and ``hex()``.\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or ``None`` if conversion is impossible. When\n the common type would be the type of ``other``, it is sufficient to\n return ``None``, since the interpreter will also ask the other\n object to attempt a coercion (but sometimes, if the implementation\n of the other type cannot be changed, it is useful to do the\n conversion to the other type here). A return value of\n ``NotImplemented`` is equivalent to returning ``None``.\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3.0, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from ``object``) never invoke the\n ``__coerce__()`` method in response to a binary operator; the only\n time ``__coerce__()`` is invoked is when the built-in function\n ``coerce()`` is called.\n\n* For most intents and purposes, an operator that returns\n ``NotImplemented`` is treated the same as one that is not\n implemented at all.\n\n* Below, ``__op__()`` and ``__rop__()`` are used to signify the\n generic method names corresponding to an operator; ``__iop__()`` is\n used for the corresponding in-place operator. For example, for the\n operator \'``+``\', ``__add__()`` and ``__radd__()`` are used for the\n left and right variant of the binary operator, and ``__iadd__()``\n for the in-place variant.\n\n* For objects *x* and *y*, first ``x.__op__(y)`` is tried. If this is\n not implemented or returns ``NotImplemented``, ``y.__rop__(x)`` is\n tried. If this is also not implemented or returns\n ``NotImplemented``, a ``TypeError`` exception is raised. But see\n the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s ``__rop__()`` method, the right operand\'s ``__rop__()``\n method is tried *before* the left operand\'s ``__op__()`` method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s ``__op__()`` method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is called\n before that type\'s ``__op__()`` or ``__rop__()`` method is called,\n but no sooner. If the coercion returns an object of a different\n type for the operand whose coercion is invoked, part of the process\n is redone using the new object.\n\n* When an in-place operator (like \'``+=``\') is used, if the left\n operand implements ``__iop__()``, it is invoked without any\n coercion. When the operation falls back to ``__op__()`` and/or\n ``__rop__()``, the normal coercion rules apply.\n\n* In ``x + y``, if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In ``x * y``, if one operator is a sequence that implements sequence\n repetition, and the other is an integer (``int`` or ``long``),\n sequence repetition is invoked.\n\n* Rich comparisons (implemented by methods ``__eq__()`` and so on)\n never use coercion. Three-way comparison (implemented by\n ``__cmp__()``) does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types ``int``,\n ``long``, ``float``, and ``complex`` do not use coercion. All these\n types implement a ``__coerce__()`` method, for use by the built-in\n ``coerce()`` function.\n\n Changed in version 2.7.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n``x.__getitem__(i)`` or implicitly as in ``x[i]``.\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print "Metaclass getattribute invoked"\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object):\n ... __metaclass__ = Meta\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print "Class getattribute invoked"\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', 'string-conversions': u'\nString conversions\n******************\n\nA string conversion is an expression list enclosed in reverse (a.k.a.\nbackward) quotes:\n\n string_conversion ::= "\'" expression_list "\'"\n\nA string conversion evaluates the contained expression list and\nconverts the resulting object into a string according to rules\nspecific to its type.\n\nIf the object is a string, a number, ``None``, or a tuple, list or\ndictionary containing only objects whose type is one of these, the\nresulting string is a valid Python expression which can be passed to\nthe built-in function ``eval()`` to yield an expression with the same\nvalue (or an approximation, if floating point numbers are involved).\n\n(In particular, converting a string adds quotes around it and converts\n"funny" characters to escape sequences that are safe to print.)\n\nRecursive objects (for example, lists or dictionaries that contain a\nreference to themselves, directly or indirectly) use ``...`` to\nindicate a recursive reference, and the result cannot be passed to\n``eval()`` to get an equal value (``SyntaxError`` will be raised\ninstead).\n\nThe built-in function ``repr()`` performs exactly the same conversion\nin its argument as enclosing it in parentheses and reverse quotes\ndoes. The built-in function ``str()`` performs a similar but more\nuser-friendly conversion.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. The two prefix characters may be\ncombined; in this case, ``\'u\'`` must appear before ``\'r\'``.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', + 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n | "b" | "B" | "br" | "Br" | "bR" | "BR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the **stringprefix** and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section *Encoding declarations*.\n\nIn plain English: String literals can be enclosed in matching single\nquotes (``\'``) or double quotes (``"``). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash (``\\``)\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter ``\'r\'`` or\n``\'R\'``; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of ``\'u\'`` or\n``\'U\'`` makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. A prefix of ``\'b\'`` or ``\'B\'`` is\nignored in Python 2; it indicates that the literal should become a\nbytes literal in Python 3 (e.g. when code is automatically converted\nwith 2to3). A ``\'u\'`` or ``\'b\'`` prefix may be followed by an ``\'r\'``\nprefix.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Individual code units which form parts of a surrogate\n pair can be encoded using this escape sequence.\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the byte\n with the given value; it is not necessary that the byte encodes a\n character in the source character set. In a Unicode literal, these\n escapes denote a Unicode character with the given value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n``r"\\n"`` consists of two characters: a backslash and a lowercase\n``\'n\'``. String quotes can be escaped with a backslash, but the\nbackslash remains in the string; for example, ``r"\\""`` is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; ``r"\\"`` is not a valid string literal (even a raw string\ncannot end in an odd number of backslashes). Specifically, *a raw\nstring cannot end in a single backslash* (since the backslash would\nescape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n\nWhen an ``\'r\'`` or ``\'R\'`` prefix is used in conjunction with a\n``\'u\'`` or ``\'U\'`` prefix, then the ``\\uXXXX`` and ``\\UXXXXXXXX``\nescape sequences are processed while *all other backslashes are left\nin the string*. For example, the string literal ``ur"\\u0062\\n"``\nconsists of three Unicode characters: \'LATIN SMALL LETTER B\', \'REVERSE\nSOLIDUS\', and \'LATIN SMALL LETTER N\'. Backslashes can be escaped with\na preceding backslash; however, both remain in the string. As a\nresult, ``\\uXXXX`` escape sequences are only recognized when there are\nan odd number of backslashes.\n', 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object of a sequence or mapping type.\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., ``x[-1]`` selects the last item of\n``x``.) The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', 'truth': u"\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0L``, ``0.0``,\n ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__nonzero__()`` or ``__len__()`` method, when that method returns\n the integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", 'try': u'\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n``try``...``except``...``finally`` did not work. ``try``...``except``\nhad to be nested in ``try``...``finally``.\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object, a tuple containing an item compatible with the\nexception, or, in the (deprecated) case of string exceptions, is the\nraised string itself (note that the object identities must match, i.e.\nit must be the same string object, not just a string with the same\nvalue).\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the ``sys`` module:\n``sys.exc_type`` receives the object identifying the exception;\n``sys.exc_value`` receives the exception\'s parameter;\n``sys.exc_traceback`` receives a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. These details are also available through the\n``sys.exc_info()`` function, which returns a tuple ``(exc_type,\nexc_value, exc_traceback)``. Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``Ellipsis``. It is used to indicate the presence of the ``...``\n syntax in a slice. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception ``OverflowError`` is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex``\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions ``chr()`` and ``ord()`` convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions ``chr()`` and ``ord()`` implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``unichr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method ``encode()`` and the\n built-in function ``unicode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm``, ``gdbm``, and ``bsddb`` provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | ``func_doc`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +-------------------------+---------------------------------+-------------+\n | ``__doc__`` | Another way of spelling | Writable |\n | | ``func_doc`` | |\n +-------------------------+---------------------------------+-------------+\n | ``func_name`` | The function\'s name | Writable |\n +-------------------------+---------------------------------+-------------+\n | ``__name__`` | Another way of spelling | Writable |\n | | ``func_name`` | |\n +-------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_defaults`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +-------------------------+---------------------------------+-------------+\n | ``func_code`` | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_globals`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_dict`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | ``func_closure`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: ``func_name`` is now writable.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or ``None``) and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: ``im_self`` is the class instance\n object, ``im_func`` is the function object; ``im_class`` is the\n class of ``im_self`` for bound methods or the class that asked\n for the method for unbound methods; ``__doc__`` is the method\'s\n documentation (same as ``im_func.__doc__``); ``__name__`` is the\n method name (same as ``im_func.__name__``); ``__module__`` is\n the name of the module the method was defined in, or ``None`` if\n unavailable.\n\n Changed in version 2.2: ``im_self`` used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For 3.0 forward-compatibility,\n ``im_func`` is also available as ``__func__``, and ``im_self``\n as ``__self__``.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its ``im_self``\n attribute is ``None`` and the method object is said to be\n unbound. When one is created by retrieving a user-defined\n function object from a class via one of its instances, its\n ``im_self`` attribute is the instance, and the method object is\n said to be bound. In either case, the new method\'s ``im_class``\n attribute is the class from which the retrieval takes place, and\n its ``im_func`` attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``im_func``\n attribute of the new instance is not the original method object\n but its ``im_func`` attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its ``im_self``\n attribute is the class itself (the same as the ``im_class``\n attribute), and its ``im_func`` attribute is the function object\n underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function (``im_func``) is called, with the\n restriction that the first argument must be an instance of the\n proper class (``im_class``) or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function (``im_func``) is called, inserting the class\n instance (``im_self``) in front of the argument list. For\n instance, when ``C`` is a class which contains a definition for\n a function ``f()``, and ``x`` is an instance of ``C``, calling\n ``x.f(1)`` is equivalent to calling ``C.f(x, 1)``.\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in ``im_self`` will actually\n be the class itself, so that calling either ``x.f(1)`` or\n ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``next()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override ``__new__()``. The arguments of the call are passed to\n ``__new__()`` and, in the typical case, to ``__init__()`` to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s ``__init__()``\n method if it has one. Any arguments are passed on to the\n ``__init__()`` method. If there is no ``__init__()`` method,\n the class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a ``__call__()`` method;\n ``x(arguments)`` is a shorthand for ``x.__call__(arguments)``.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section *Class definitions*). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., ``C.x`` is\n translated to ``C.__dict__["x"]`` (although for new-style classes\n in particular there are a number of hooks which allow for other\n means of locating attributes). When the attribute name is not found\n there, the attribute search continues in the base classes. For\n old-style classes, the search is depth-first, left-to-right in the\n order of occurrence in the base class list. New-style classes use\n the more complex C3 method resolution order which behaves correctly\n even in the presence of \'diamond\' inheritance structures where\n there are multiple inheritance paths leading back to a common\n ancestor. Additional details on the C3 MRO used by new-style\n classes can be found in the documentation accompanying the 2.3\n release at http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a user-defined function object or an unbound user-defined method\n object whose associated class is either ``C`` or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose ``im_class`` attribute is ``C``. When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose ``im_class`` and ``im_self`` attributes are\n both ``C``. When it would yield a static method object, it is\n transformed into the object wrapped by the static method object.\n See section *Implementing Descriptors* for another way in which\n attributes retrieved from a class may differ from those actually\n contained in its ``__dict__`` (note that only new-style classes\n support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it ``C``) of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n ``im_class`` attribute is ``C`` and whose ``im_self`` attribute is\n the instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class ``C``; see\n above under "Classes". See section *Implementing Descriptors* for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s ``__dict__``. If no class attribute is found, and the\n object\'s class has a ``__getattr__()`` method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the ``open()`` built-in function, and also by ``os.popen()``,\n ``os.fdopen()``, and the ``makefile()`` method of socket objects\n (and perhaps by other functions or methods provided by extension\n modules). The objects ``sys.stdin``, ``sys.stdout`` and\n ``sys.stderr`` are initialized to file objects corresponding to the\n interpreter\'s standard input, output and error streams. See *File\n Objects* for complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_restricted`` is a flag indicating whether the function is\n executing in restricted execution mode; ``f_lasti`` gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_exc_type``, ``f_exc_value``,\n ``f_exc_traceback`` represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); ``f_lineno``\n is the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as ``sys.exc_traceback``,\n and also as the third item of the tuple returned by\n ``sys.exc_info()``. The latter is the preferred interface,\n since it works correctly when the program is using multiple\n threads. When the program contains no suitable handler, the\n stack trace is written (nicely formatted) to the standard error\n stream; if the interpreter is interactive, it is also made\n available to the user as ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., ``a[i:j:step]``,\n ``a[i:j, k:l]``, or ``a[..., i:j]``. They are also created by\n the built-in ``slice()`` function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': u'\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key is\n specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n\n viewitems()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.viewkeys()``, ``dict.viewvalues()`` and\n``dict.viewitems()`` are *view objects*. They provide a dynamic view\non the dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n', + 'typesmapping': u'\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key is\n specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 1, "two": 2}``:\n\n * ``dict(one=1, two=2)``\n\n * ``dict({\'one\': 1, \'two\': 2})``\n\n * ``dict(zip((\'one\', \'two\'), (1, 2)))``\n\n * ``dict([[\'two\', 2], [\'one\', 1]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n New in version 2.5: If a subclass of dict defines a method\n ``__missing__()``, if the key *key* is not present, the\n ``d[key]`` operation calls that method with the key *key* as\n argument. The ``d[key]`` operation then returns or raises\n whatever is returned or raised by the ``__missing__(key)`` call\n if the key is not present. No other operations or methods invoke\n ``__missing__()``. If ``__missing__()`` is not defined,\n ``KeyError`` is raised. ``__missing__()`` must be a method; it\n cannot be an instance variable. For an example, see\n ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iterkeys()``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. ``has_key()``\n is deprecated in favor of ``key in d``.\n\n items()\n\n Return a copy of the dictionary\'s list of ``(key, value)``\n pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If ``items()``, ``keys()``, ``values()``, ``iteritems()``,\n ``iterkeys()``, and ``itervalues()`` are called with no\n intervening modifications to the dictionary, the lists will\n directly correspond. This allows the creation of ``(value,\n key)`` pairs using ``zip()``: ``pairs = zip(d.values(),\n d.keys())``. The same relationship holds for the ``iterkeys()``\n and ``itervalues()`` methods: ``pairs = zip(d.itervalues(),\n d.iterkeys())`` provides the same value for ``pairs``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.iteritems()]``.\n\n iteritems()\n\n Return an iterator over the dictionary\'s ``(key, value)`` pairs.\n See the note for ``dict.items()``.\n\n Using ``iteritems()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n ``dict.items()``.\n\n Using ``iterkeys()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for ``dict.items()``.\n\n Using ``itervalues()`` while adding or deleting entries in the\n dictionary may raise a ``RuntimeError`` or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for ``dict.items()``.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for ``dict.items()``.\n\n viewitems()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.viewkeys()``, ``dict.viewvalues()`` and\n``dict.viewitems()`` are *view objects*. They provide a dynamic view\non the dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n', 'typesmethods': u"\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nThe implementation adds two special read-only attributes to class\ninstance methods: ``m.im_self`` is the object on which the method\noperates, and ``m.im_func`` is the function implementing the method.\nCalling ``m(arg-1, arg-2, ..., arg-n)`` is completely equivalent to\ncalling ``m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)``.\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its ``im_self`` attribute\nwill be ``None`` and if called, an explicit ``self`` object must be\npassed as the first argument. In this case, ``self`` must be an\ninstance of the unbound method's class (or a subclass of that class),\notherwise a ``TypeError`` is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.im_func``), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set a method attribute results in a ``TypeError`` being\nraised. In order to set a method attribute, you need to explicitly\nset it on the underlying function object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.im_func.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n", 'typesmodules': u"\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n", - 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``buffer``, ``xrange``\n************************************************************************************\n\nThere are six sequence types: strings, Unicode strings, lists, tuples,\nbuffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbuffer, xrange* section. To output formatted strings use template\nstrings or the ``%`` operator described in the *String Formatting\nOperations* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with only its first character\n capitalized.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n', - 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList objects support additional operations that allow in-place\nmodification of the object. Other mutable sequence types (when added\nto the language) should also support these operations. Strings and\ntuples are immutable sequence types: such objects cannot be modified\nonce created. The following operations are defined on mutable sequence\ntypes (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n", + 'typesseq': u'\nSequence Types --- ``str``, ``unicode``, ``list``, ``tuple``, ``bytearray``, ``buffer``, ``xrange``\n***************************************************************************************************\n\nThere are seven sequence types: strings, Unicode strings, lists,\ntuples, bytearrays, buffers, and xrange objects.\n\nFor other containers see the built in ``dict`` and ``set`` classes,\nand the ``collections`` module.\n\nString literals are written in single or double quotes: ``\'xyzzy\'``,\n``"frobozz"``. See *String literals* for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding ``\'u\'`` character: ``u\'abc\'``, ``u"def"``. In\naddition to the functionality described here, there are also string-\nspecific methods described in the *String Methods* section. Lists are\nconstructed with square brackets, separating items with commas: ``[a,\nb, c]``. Tuples are constructed by the comma operator (not within\nsquare brackets), with or without enclosing parentheses, but an empty\ntuple must have the enclosing parentheses, such as ``a, b, c`` or\n``()``. A single item tuple must have a trailing comma, such as\n``(d,)``.\n\nBytearray objects are created with the built-in function\n``bytearray()``.\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function ``buffer()``. They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n``xrange()`` function. They don\'t support slicing, concatenation or\nrepetition, and using ``in``, ``not in``, ``min()`` or ``max()`` on\nthem is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.index(i)`` | index of the first occurence of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n| ``s.count(i)`` | total number of occurences of | |\n| | *i* in *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the ``in`` and ``not\n in`` operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n``bytearray`` objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange* section. To output formatted strings use\ntemplate strings or the ``%`` operator described in the *String\nFormatting Operations* section. Also, see the ``re`` module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n ``\'strict\'``, meaning that encoding errors raise ``UnicodeError``.\n Other possible values are ``\'ignore\'``, ``\'replace\'`` and any other\n name registered via ``codecs.register_error()``, see section *Codec\n Base Classes*.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for ``\'xmlcharrefreplace\'`` and\n ``\'backslashreplace\'`` and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3.0,\n and should be preferred to the ``%`` formatting described in\n *String Formatting Operations* in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a ``None`` *table* argument.\n\n For Unicode objects, the ``translate()`` method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or ``None``. Unmapped characters\n are left untouched. Characters mapped to ``None`` are deleted.\n Note, a more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see ``encodings.cp1251``\n for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return ``True`` if there are only numeric characters in S,\n ``False`` otherwise. Numeric characters include digit characters,\n and all characters that have the Unicode numeric value property,\n e.g. U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return ``True`` if there are only decimal characters in S,\n ``False`` otherwise. Decimal characters include digit characters,\n and all characters that that can be used to form decimal-radix\n numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the\n``%`` operator (modulo). This is also known as the string\n*formatting* or *interpolation* operator. Given ``format % values``\n(where *format* is a string or Unicode object), ``%`` conversion\nspecifications in *format* are replaced with zero or more elements of\n*values*. The effect is similar to the using ``sprintf()`` in the C\nlanguage. If *format* is a Unicode object, or if any of the objects\nbeing converted using the ``%s`` conversion are Unicode objects, the\nresult will also be a Unicode object.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(number)03d quote types.\' % \\\n... {"language": "Python", "number": 2}\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The ``%r`` conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a ``unicode`` string, the\n resulting string will also be ``unicode``.\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 2.7: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nXRange Type\n===========\n\nThe ``xrange`` type is an immutable sequence which is commonly used\nfor looping. The advantage of the ``xrange`` type is that an\n``xrange`` object will always take the same amount of memory, no\nmatter the size of the range it represents. There are no consistent\nperformance advantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn\'t have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n', + 'typesseq-mutable': u"\nMutable Sequence Types\n**********************\n\nList and ``bytearray`` objects support additional operations that\nallow in-place modification of the object. Other mutable sequence\ntypes (when added to the language) should also support these\noperations. Strings and tuples are immutable sequence types: such\nobjects cannot be modified once created. The following operations are\ndefined on mutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | (2) |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (4) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (6) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])`` | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted multiple\n parameters and implicitly joined them into a tuple; this no longer\n works in Python 2.0. Use of this misfeature has been deprecated\n since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the list length is added, as for slice indices. If it is\n still negative, it is truncated to zero, as for slice indices.\n\n Changed in version 2.3: Previously, ``index()`` didn't have\n arguments for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n ``insert()`` method, the list length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The ``pop()`` method is only supported by the list and array types.\n The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n7. The ``sort()`` and ``reverse()`` methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don't return the\n sorted or reversed list.\n\n8. The ``sort()`` method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: ``cmp=lambda x,y:\n cmp(x.lower(), y.lower())``. The default value is ``None``.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n ``functools.cmp_to_key()`` to convert an old-style *cmp* function\n to a *key* function.\n\n Changed in version 2.3: Support for ``None`` as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the ``sort()`` method is guaranteed to be\n stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python 2.3 and newer makes the\n list appear empty for the duration, and raises ``ValueError`` if\n it can detect that the list has been mutated during a sort.\n", 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\nplain or long integer argument. The bitwise inversion of ``x`` is\ndefined as ``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', 'while': u'\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', - 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', + 'with': u'\nThe ``with`` statement\n**********************\n\nNew in version 2.5.\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the **with_item**)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the ``with`` statement is only allowed when the\n ``with_statement`` feature has been enabled. It is always enabled\n in Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', 'yield': u'\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s ``next()``\nmethod repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of **expression_list** is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nAs of Python version 2.5, the ``yield`` statement is now allowed in\nthe ``try`` clause of a ``try`` ... ``finally`` construct. If the\ngenerator is not resumed before it is finalized (by reaching a zero\nreference count or by being garbage collected), the generator-\niterator\'s ``close()`` method will be called, allowing any pending\n``finally`` clauses to execute.\n\nNote: In Python 2.2, the ``yield`` statement was only allowed when the\n ``generators`` feature has been enabled. This ``__future__`` import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'} diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -47,7 +47,7 @@ What's New in Python 2.7.2? =========================== -*Release date: 2011-06-XX* +*Release date: 2011-06-11* Library ------- diff --git a/Misc/RPM/python-2.7.spec b/Misc/RPM/python-2.7.spec --- a/Misc/RPM/python-2.7.spec +++ b/Misc/RPM/python-2.7.spec @@ -39,7 +39,7 @@ %define name python #--start constants-- -%define version 2.7.2rc1 +%define version 2.7.2 %define libvers 2.7 #--end constants-- %define release 1pydotorg -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 17:01:04 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 17:01:04 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4xKTogYnVtcCB0byAzLjEu?= =?utf8?q?4?= Message-ID: http://hg.python.org/cpython/rev/c918ec9f3a76 changeset: 70780:c918ec9f3a76 branch: 3.1 tag: v3.1.4 parent: 70769:8625ce7da152 user: Benjamin Peterson date: Sat Jun 11 09:58:58 2011 -0500 summary: bump to 3.1.4 files: Include/patchlevel.h | 6 +++--- Lib/distutils/__init__.py | 2 +- Lib/idlelib/idlever.py | 2 +- Misc/NEWS | 2 +- Misc/RPM/python-3.1.spec | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -19,11 +19,11 @@ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 1 #define PY_MICRO_VERSION 4 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.1.4rc1" +#define PY_VERSION "3.1.4" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -15,5 +15,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "3.1.4rc1" +__version__ = "3.1.4" #--end constants-- diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1,1 +1,1 @@ -IDLE_VERSION = "3.1.4rc1" +IDLE_VERSION = "3.1.4" diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -5,7 +5,7 @@ What's New in Python 3.1.4? =========================== -*Release date: 2011-05-XX* +*Release date: 2011-06-11* Library ------- diff --git a/Misc/RPM/python-3.1.spec b/Misc/RPM/python-3.1.spec --- a/Misc/RPM/python-3.1.spec +++ b/Misc/RPM/python-3.1.spec @@ -34,7 +34,7 @@ %define name python #--start constants-- -%define version 3.1.4rc1 +%define version 3.1.4 %define libvers 3.1 #--end constants-- %define release 1pydotorg -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 17:01:04 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 17:01:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_Added_tag_v3=2E?= =?utf8?q?1=2E4_for_changeset_c918ec9f3a76?= Message-ID: http://hg.python.org/cpython/rev/feae9f9e9f30 changeset: 70781:feae9f9e9f30 branch: 3.1 user: Benjamin Peterson date: Sat Jun 11 09:59:17 2011 -0500 summary: Added tag v3.1.4 for changeset c918ec9f3a76 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -76,3 +76,4 @@ d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1 a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3 32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1 +c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 17:01:05 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 17:01:05 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1?= Message-ID: http://hg.python.org/cpython/rev/9be10dad0d51 changeset: 70782:9be10dad0d51 branch: 3.2 parent: 70773:3cf5d61fd6d7 parent: 70781:feae9f9e9f30 user: Benjamin Peterson date: Sat Jun 11 10:01:14 2011 -0500 summary: merge 3.1 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -76,6 +76,7 @@ d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1 a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3 32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1 +c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4 b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1 56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2 da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 17:01:06 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 17:01:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/96471e9722c7 changeset: 70783:96471e9722c7 parent: 70775:e572a97a1bd1 parent: 70782:9be10dad0d51 user: Benjamin Peterson date: Sat Jun 11 10:01:35 2011 -0500 summary: merge 3.2 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -76,6 +76,7 @@ d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1 a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3 32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1 +c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4 b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1 56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2 da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 18:34:07 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 18:34:07 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4xKTogb250byAzLjEuNQ==?= Message-ID: http://hg.python.org/cpython/rev/6f0bcfc17a9e changeset: 70784:6f0bcfc17a9e branch: 3.1 parent: 70781:feae9f9e9f30 user: Benjamin Peterson date: Sat Jun 11 11:33:01 2011 -0500 summary: onto 3.1.5 files: Include/patchlevel.h | 2 +- Misc/NEWS | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.1.4" +#define PY_VERSION "3.1.4+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,18 @@ Python News +++++++++++ +What's New in Python 3.1.5? +=========================== + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 3.1.4? =========================== -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 18:34:07 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 18:34:07 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogb250byAyLjcuMw==?= Message-ID: http://hg.python.org/cpython/rev/35c5d20edb38 changeset: 70785:35c5d20edb38 branch: 2.7 parent: 70779:31afae5c2a8d user: Benjamin Peterson date: Sat Jun 11 11:33:54 2011 -0500 summary: onto 2.7.3 files: Include/patchlevel.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "2.7.2" +#define PY_VERSION "2.7.2+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 18:34:09 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 18:34:09 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1?= Message-ID: http://hg.python.org/cpython/rev/1ab1365e6b7a changeset: 70786:1ab1365e6b7a branch: 3.2 parent: 70782:9be10dad0d51 parent: 70784:6f0bcfc17a9e user: Benjamin Peterson date: Sat Jun 11 11:34:31 2011 -0500 summary: merge 3.1 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 18:34:09 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 18:34:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/544b52f13153 changeset: 70787:544b52f13153 parent: 70783:96471e9722c7 parent: 70786:1ab1365e6b7a user: Benjamin Peterson date: Sat Jun 11 11:34:37 2011 -0500 summary: merge 3.2 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 18:58:25 2011 From: python-checkins at python.org (charles-francois.natali) Date: Sat, 11 Jun 2011 18:58:25 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312287=3A_In_ossaud?= =?utf8?q?iodev=2C_check_that_the_device_isn=27t_closed_in_several?= Message-ID: http://hg.python.org/cpython/rev/d0952a2fb7bd changeset: 70788:d0952a2fb7bd user: Charles-Fran?ois Natali date: Sat Jun 11 18:58:24 2011 +0200 summary: Issue #12287: In ossaudiodev, check that the device isn't closed in several methods. files: Lib/test/test_ossaudiodev.py | 16 ++++ Misc/NEWS | 3 + Modules/ossaudiodev.c | 91 ++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_ossaudiodev.py b/Lib/test/test_ossaudiodev.py --- a/Lib/test/test_ossaudiodev.py +++ b/Lib/test/test_ossaudiodev.py @@ -170,6 +170,22 @@ pass self.assertTrue(dsp.closed) + def test_on_closed(self): + dsp = ossaudiodev.open('w') + dsp.close() + self.assertRaises(ValueError, dsp.fileno) + self.assertRaises(ValueError, dsp.read, 1) + self.assertRaises(ValueError, dsp.write, b'x') + self.assertRaises(ValueError, dsp.writeall, b'x') + self.assertRaises(ValueError, dsp.bufsize) + self.assertRaises(ValueError, dsp.obufcount) + self.assertRaises(ValueError, dsp.obufcount) + self.assertRaises(ValueError, dsp.obuffree) + self.assertRaises(ValueError, dsp.getptr) + + mixer = ossaudiodev.openmixer() + mixer.close() + self.assertRaises(ValueError, mixer.fileno) def test_main(): try: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #12287: In ossaudiodev, check that the device isn't closed in several + methods. + - Issue #12009: Fixed regression in netrc file comment handling. - Issue #12246: Warn and fail when trying to install a third-party project from diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -213,6 +213,21 @@ * Helper functions */ +/* Check if a given file descriptor is valid (i.e. hasn't been closed). + * If true, return 1. Otherwise, raise ValueError and return 0. + */ +static int _is_fd_valid(int fd) +{ + /* the FD is set to -1 in oss_close()/oss_mixer_close() */ + if (fd >= 0) { + return 1; + } else { + PyErr_SetString(PyExc_ValueError, + "Operation on closed OSS device."); + return 0; + } +} + /* _do_ioctl_1() is a private helper function used for the OSS ioctls -- SNDCTL_DSP_{SETFMT,CHANNELS,SPEED} -- that that are called from C like this: @@ -300,6 +315,9 @@ static PyObject * oss_nonblock(oss_audio_t *self, PyObject *unused) { + if (!_is_fd_valid(self->fd)) + return NULL; + /* Hmmm: it doesn't appear to be possible to return to blocking mode once we're in non-blocking mode! */ if (ioctl(self->fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) @@ -311,6 +329,9 @@ static PyObject * oss_setfmt(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1(self->fd, args, "setfmt", SNDCTL_DSP_SETFMT); } @@ -318,6 +339,10 @@ oss_getfmts(oss_audio_t *self, PyObject *unused) { int mask; + + if (!_is_fd_valid(self->fd)) + return NULL; + if (ioctl(self->fd, SNDCTL_DSP_GETFMTS, &mask) == -1) return PyErr_SetFromErrno(PyExc_IOError); return PyLong_FromLong(mask); @@ -326,30 +351,45 @@ static PyObject * oss_channels(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1(self->fd, args, "channels", SNDCTL_DSP_CHANNELS); } static PyObject * oss_speed(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1(self->fd, args, "speed", SNDCTL_DSP_SPEED); } static PyObject * oss_sync(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_0(self->fd, args, "sync", SNDCTL_DSP_SYNC); } static PyObject * oss_reset(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_0(self->fd, args, "reset", SNDCTL_DSP_RESET); } static PyObject * oss_post(oss_audio_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_0(self->fd, args, "post", SNDCTL_DSP_POST); } @@ -364,6 +404,9 @@ char *cp; PyObject *rv; + if (!_is_fd_valid(self->fd)) + return NULL; + if (!PyArg_ParseTuple(args, "i:read", &size)) return NULL; rv = PyBytes_FromStringAndSize(NULL, size); @@ -391,6 +434,9 @@ char *cp; int rv, size; + if (!_is_fd_valid(self->fd)) + return NULL; + if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) { return NULL; } @@ -422,6 +468,9 @@ mode, the behaviour of write() and writeall() from Python is indistinguishable. */ + if (!_is_fd_valid(self->fd)) + return NULL; + if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) return NULL; @@ -489,6 +538,9 @@ static PyObject * oss_fileno(oss_audio_t *self, PyObject *unused) { + if (!_is_fd_valid(self->fd)) + return NULL; + return PyLong_FromLong(self->fd); } @@ -503,6 +555,9 @@ int fmt, channels, rate; PyObject * rv; /* return tuple (fmt, channels, rate) */ + if (!_is_fd_valid(self->fd)) + return NULL; + if (!PyArg_ParseTuple(args, "iii|i:setparameters", &wanted_fmt, &wanted_channels, &wanted_rate, &strict)) @@ -593,6 +648,9 @@ audio_buf_info ai; int nchannels=0, ssize=0; + if (!_is_fd_valid(self->fd)) + return NULL; + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { PyErr_SetFromErrno(PyExc_IOError); return NULL; @@ -612,6 +670,9 @@ audio_buf_info ai; int nchannels=0, ssize=0; + if (!_is_fd_valid(self->fd)) + return NULL; + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { PyErr_SetFromErrno(PyExc_IOError); return NULL; @@ -632,6 +693,9 @@ audio_buf_info ai; int nchannels=0, ssize=0; + if (!_is_fd_valid(self->fd)) + return NULL; + if (_ssize(self, &nchannels, &ssize) < 0 || !nchannels || !ssize) { PyErr_SetFromErrno(PyExc_IOError); return NULL; @@ -649,6 +713,9 @@ count_info info; int req; + if (!_is_fd_valid(self->fd)) + return NULL; + if (self->mode == O_RDONLY) req = SNDCTL_DSP_GETIPTR; else @@ -679,6 +746,9 @@ static PyObject * oss_mixer_fileno(oss_mixer_t *self, PyObject *unused) { + if (!_is_fd_valid(self->fd)) + return NULL; + return PyLong_FromLong(self->fd); } @@ -687,6 +757,9 @@ static PyObject * oss_mixer_controls(oss_mixer_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1_internal(self->fd, args, "controls", SOUND_MIXER_READ_DEVMASK); } @@ -694,6 +767,9 @@ static PyObject * oss_mixer_stereocontrols(oss_mixer_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1_internal(self->fd, args, "stereocontrols", SOUND_MIXER_READ_STEREODEVS); } @@ -701,6 +777,9 @@ static PyObject * oss_mixer_reccontrols(oss_mixer_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1_internal(self->fd, args, "reccontrols", SOUND_MIXER_READ_RECMASK); } @@ -710,6 +789,9 @@ { int channel, volume; + if (!_is_fd_valid(self->fd)) + return NULL; + /* Can't use _do_ioctl_1 because of encoded arg thingy. */ if (!PyArg_ParseTuple(args, "i:get", &channel)) return NULL; @@ -730,6 +812,9 @@ { int channel, volume, leftVol, rightVol; + if (!_is_fd_valid(self->fd)) + return NULL; + /* Can't use _do_ioctl_1 because of encoded arg thingy. */ if (!PyArg_ParseTuple(args, "i(ii):set", &channel, &leftVol, &rightVol)) return NULL; @@ -755,6 +840,9 @@ static PyObject * oss_mixer_get_recsrc(oss_mixer_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1_internal(self->fd, args, "get_recsrc", SOUND_MIXER_READ_RECSRC); } @@ -762,6 +850,9 @@ static PyObject * oss_mixer_set_recsrc(oss_mixer_t *self, PyObject *args) { + if (!_is_fd_valid(self->fd)) + return NULL; + return _do_ioctl_1(self->fd, args, "set_recsrc", SOUND_MIXER_WRITE_RECSRC); } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:42 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Move_useful_function_to_pac?= =?utf8?q?kaging=2Eutil=2E?= Message-ID: http://hg.python.org/cpython/rev/303e3693d634 changeset: 70789:303e3693d634 parent: 70765:11b5d98feb05 user: ?ric Araujo date: Fri Jun 10 23:26:31 2011 +0200 summary: Move useful function to packaging.util. Original patch by Erik Bray as part of #11595, changed by me to improve readability. files: Lib/packaging/config.py | 19 +++++++------------ Lib/packaging/util.py | 17 +++++++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -9,7 +9,8 @@ from packaging import logger from packaging.errors import PackagingOptionError from packaging.compiler.extension import Extension -from packaging.util import check_environ, iglob, resolve_name, strtobool +from packaging.util import (check_environ, iglob, resolve_name, strtobool, + split_multiline) from packaging.compiler import set_compiler from packaging.command import set_command from packaging.markers import interpret @@ -124,12 +125,6 @@ # XXX return value - def _multiline(self, value): - value = [v for v in - [v.strip() for v in value.split('\n')] - if v != ''] - return value - def _read_setup_cfg(self, parser, cfg_filename): cfg_directory = os.path.dirname(os.path.abspath(cfg_filename)) content = {} @@ -155,7 +150,7 @@ for key, value in content['metadata'].items(): key = key.replace('_', '-') if metadata.is_multi_field(key): - value = self._multiline(value) + value = split_multiline(value) if key == 'project-url': value = [(label.strip(), url.strip()) @@ -192,7 +187,7 @@ files = content['files'] self.dist.package_dir = files.pop('packages_root', None) - files = dict((key, self._multiline(value)) for key, value in + files = dict((key, split_multiline(value)) for key, value in files.items()) self.dist.packages = [] @@ -310,7 +305,7 @@ opt = opt.replace('-', '_') if opt == 'sub_commands': - val = self._multiline(val) + val = split_multiline(val) if isinstance(val, str): val = [val] @@ -348,14 +343,14 @@ raise PackagingOptionError(msg) def _load_compilers(self, compilers): - compilers = self._multiline(compilers) + compilers = split_multiline(compilers) if isinstance(compilers, str): compilers = [compilers] for compiler in compilers: set_compiler(compiler.strip()) def _load_commands(self, commands): - commands = self._multiline(commands) + commands = split_multiline(commands) if isinstance(commands, str): commands = [commands] for command in commands: diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -250,6 +250,14 @@ return words +def split_multiline(value): + """Split a multiline string into a list, excluding blank lines.""" + + return [element for element in + (line.strip() for line in value.split('\n')) + if element] + + def execute(func, args, msg=None, verbose=0, dry_run=False): """Perform some action that affects the outside world. @@ -542,18 +550,15 @@ def _is_package(path): - if not os.path.isdir(path): - return False - return os.path.isfile(os.path.join(path, '__init__.py')) + return os.path.isdir(path) and os.path.isfile( + os.path.join(path, '__init__.py')) # Code taken from the pip project def _is_archive_file(name): archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar') ext = splitext(name)[1].lower() - if ext in archives: - return True - return False + return ext in archives def _under(path, root): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:43 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:43 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_assorted_bugs_in_packag?= =?utf8?b?aW5nLnV0aWwuY2ZnX3RvX2FyZ3MgKCMxMTU5NSku?= Message-ID: http://hg.python.org/cpython/rev/06670bd0e59e changeset: 70790:06670bd0e59e user: ?ric Araujo date: Fri Jun 10 23:52:26 2011 +0200 summary: Fix assorted bugs in packaging.util.cfg_to_args (#11595). Original patch by Erik Bray. files: Lib/packaging/tests/test_util.py | 48 +++++++++++++++++-- Lib/packaging/util.py | 31 ++++++++---- Misc/ACKS | 1 + Misc/NEWS | 4 + 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -8,16 +8,18 @@ from io import StringIO from packaging.tests import support, unittest +from packaging.tests.test_config import SETUP_CFG from packaging.errors import ( PackagingPlatformError, PackagingByteCompileError, PackagingFileError, PackagingExecError, InstallationException) from packaging import util +from packaging.dist import Distribution from packaging.util import ( convert_path, change_root, split_quoted, strtobool, rfc822_escape, get_compiler_versions, _MAC_OS_X_LD_VERSION, byte_compile, find_packages, spawn, get_pypirc_path, generate_pypirc, read_pypirc, resolve_name, iglob, RICH_GLOB, egginfo_to_distinfo, is_setuptools, is_distutils, is_packaging, - get_install_method) + get_install_method, cfg_to_args) PYPIRC = """\ @@ -88,13 +90,15 @@ support.LoggingCatcher, unittest.TestCase): - restore_environ = ['HOME'] + restore_environ = ['HOME', 'PLAT'] def setUp(self): super(UtilTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - self.rc = os.path.join(self.tmp_dir, '.pypirc') - os.environ['HOME'] = self.tmp_dir + self.addCleanup(os.chdir, os.getcwd()) + tempdir = self.mkdtemp() + self.rc = os.path.join(tempdir, '.pypirc') + os.environ['HOME'] = tempdir + os.chdir(tempdir) # saving the environment self.name = os.name self.platform = sys.platform @@ -103,7 +107,6 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive - #self._config_vars = copy(sysconfig._config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -137,7 +140,6 @@ os.uname = self.uname else: del os.uname - #sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen sys.old_stdout = self.old_stdout @@ -491,6 +493,38 @@ content = f.read() self.assertEqual(content, WANTED) + def test_cfg_to_args(self): + opts = {'description-file': 'README', 'extra-files': '', + 'setup-hook': 'packaging.tests.test_config.hook'} + self.write_file('setup.cfg', SETUP_CFG % opts) + self.write_file('README', 'loooong description') + + args = cfg_to_args() + # use Distribution to get the contents of the setup.cfg file + dist = Distribution() + dist.parse_config_files() + metadata = dist.metadata + + self.assertEqual(args['name'], metadata['Name']) + # + .dev1 because the test SETUP_CFG also tests a hook function in + # test_config.py for appending to the version string + self.assertEqual(args['version'] + '.dev1', metadata['Version']) + self.assertEqual(args['author'], metadata['Author']) + self.assertEqual(args['author_email'], metadata['Author-Email']) + self.assertEqual(args['maintainer'], metadata['Maintainer']) + self.assertEqual(args['maintainer_email'], + metadata['Maintainer-Email']) + self.assertEqual(args['description'], metadata['Summary']) + self.assertEqual(args['long_description'], metadata['Description']) + self.assertEqual(args['classifiers'], metadata['Classifier']) + self.assertEqual(args['requires'], metadata['Requires-Dist']) + self.assertEqual(args['provides'], metadata['Provides-Dist']) + + self.assertEqual(args['package_dir'].get(''), dist.package_dir) + self.assertEqual(args['packages'], dist.packages) + self.assertEqual(args['scripts'], dist.scripts) + self.assertEqual(args['py_modules'], dist.py_modules) + class GlobTestCaseBase(support.TempdirManager, support.LoggingCatcher, diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1015,16 +1015,20 @@ "requires": ("metadata", "requires_dist"), "provides": ("metadata", "provides_dist"), # ** "obsoletes": ("metadata", "obsoletes_dist"), # ** + "package_dir": ("files", 'packages_root'), "packages": ("files",), "scripts": ("files",), "py_modules": ("files", "modules"), # ** } MULTI_FIELDS = ("classifiers", + "platforms", "requires", - "platforms", + "provides", + "obsoletes", "packages", - "scripts") + "scripts", + "py_modules") def has_get_option(config, section, option): if config.has_option(section, option): @@ -1036,9 +1040,9 @@ # The real code starts here config = RawConfigParser() - if not os.path.exists(file): + if not os.path.exists(path): raise PackagingFileError("file '%s' does not exist" % - os.path.abspath(file)) + os.path.abspath(path)) config.read(path) kwargs = {} @@ -1055,17 +1059,24 @@ in_cfg_value = has_get_option(config, section, option) if not in_cfg_value: # There is no such option in the setup.cfg - if arg == "long_description": - filename = has_get_option(config, section, "description_file") - if filename: - with open(filename) as fp: - in_cfg_value = fp.read() + if arg == 'long_description': + filenames = has_get_option(config, section, 'description-file') + if filenames: + filenames = split_multiline(filenames) + in_cfg_value = [] + for filename in filenames: + with open(filename) as fp: + in_cfg_value.append(fp.read()) + in_cfg_value = '\n\n'.join(in_cfg_value) else: continue + if arg == 'package_dir' and in_cfg_value: + in_cfg_value = {'': in_cfg_value} + if arg in MULTI_FIELDS: # support multiline options - in_cfg_value = in_cfg_value.strip().split('\n') + in_cfg_value = split_multiline(in_cfg_value) kwargs[arg] = in_cfg_value diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -116,6 +116,7 @@ Georg Brandl Christopher Brannon Terrence Brannon +Erik Bray Brian Brazil Dave Brennan Tom Bridgman diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,10 @@ Library ------- +- Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a + compatibility helper for the distutils-packaging transition. Original patch + by Erik Bray. + - Issue #12246: Warn and fail when trying to install a third-party project from an uninstalled Python (built in a source checkout). Original patch by Tshepang Lekhonkhobe. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:43 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:43 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_setup=2Ecfg=3A_Document_tha?= =?utf8?q?t_description-file_can_contain_more_than_one_file?= Message-ID: http://hg.python.org/cpython/rev/c624c08b70e1 changeset: 70791:c624c08b70e1 user: ?ric Araujo date: Sat Jun 11 00:21:18 2011 +0200 summary: setup.cfg: Document that description-file can contain more than one file files: Doc/packaging/setupcfg.rst | 1 + Lib/packaging/config.py | 13 +++++-------- Lib/packaging/tests/test_config.py | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -285,6 +285,7 @@ description-file Path to a text file that will be used to fill the ``description`` field. + Multiple values are accepted; they must be separated by whitespace. ``description-file`` and ``description`` are mutually exclusive. *optional* diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -163,21 +163,18 @@ "mutually exclusive") raise PackagingOptionError(msg) - if isinstance(value, list): - filenames = value - else: - filenames = value.split() + filenames = value.split() - # concatenate each files - value = '' + # concatenate all files + value = [] for filename in filenames: # will raise if file not found with open(filename) as description_file: - value += description_file.read().strip() + '\n' + value.append(description_file.read().strip()) # add filename as a required file if filename not in metadata.requires_files: metadata.requires_files.append(filename) - value = value.strip() + value = '\n'.join(value).strip() key = 'description' if metadata.is_metadata_field(key): diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -327,7 +327,7 @@ self.assertIn('could not import setup_hook', logs[0]) def test_metadata_requires_description_files_missing(self): - self.write_setup({'description-file': 'README\n README2'}) + self.write_setup({'description-file': 'README README2'}) self.write_file('README', 'yeah') self.write_file('README2', 'yeah') os.mkdir('src') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:44 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Allow_multiple_setup_hooks_?= =?utf8?b?aW4gcGFja2FnaW5n4oCZcyBzZXR1cC5jZmcgZmlsZXMgKCMxMjI0MCku?= Message-ID: http://hg.python.org/cpython/rev/5f0cd4844061 changeset: 70792:5f0cd4844061 user: ?ric Araujo date: Sat Jun 11 00:33:38 2011 +0200 summary: Allow multiple setup hooks in packaging?s setup.cfg files (#12240). Original patch by Erik Bray. files: Doc/packaging/setupcfg.rst | 14 ++++-- Lib/packaging/config.py | 37 +++++++++-------- Lib/packaging/tests/test_config.py | 36 ++++++++++++++--- Lib/packaging/tests/test_util.py | 2 +- Misc/NEWS | 3 + 5 files changed, 61 insertions(+), 31 deletions(-) diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -176,15 +176,19 @@ compilers = hotcompiler.SmartCCompiler -setup_hook - defines a callable that will be called right after the - :file:`setup.cfg` file is read. The callable receives the configuration - in form of a mapping and can make some changes to it. *optional* +setup_hooks + Defines a list of callables to be called right after the :file:`setup.cfg` + file is read, before any other processing. The callables are executed in the + order they're found in the file; if one of them cannot be found, tools should + not stop, but for example produce a warning and continue with the next line. + Each callable receives the configuration as a dictionary (keys are + :file:`setup.cfg` sections, values are dictionaries of fields) and can make + any changes to it. *optional*, *multi* Example:: [global] - setup_hook = package.setup.customize_dist + setup_hooks = package.setup.customize_dist Metadata diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -61,17 +61,15 @@ class Config: - """Reads configuration files and work with the Distribution instance - """ + """Class used to work with configuration files""" def __init__(self, dist): self.dist = dist - self.setup_hook = None + self.setup_hooks = [] - def run_hook(self, config): - if self.setup_hook is None: - return - # the hook gets only the config - self.setup_hook(config) + def run_hooks(self, config): + """Run setup hooks in the order defined in the spec.""" + for hook in self.setup_hooks: + hook(config) def find_config_files(self): """Find as many configuration files as should be processed for this @@ -131,17 +129,20 @@ for section in parser.sections(): content[section] = dict(parser.items(section)) - # global:setup_hook is called *first* + # global setup hooks are called first if 'global' in content: - if 'setup_hook' in content['global']: - setup_hook = content['global']['setup_hook'] - try: - self.setup_hook = resolve_name(setup_hook) - except ImportError as e: - logger.warning('could not import setup_hook: %s', - e.args[0]) - else: - self.run_hook(content) + if 'setup_hooks' in content['global']: + setup_hooks = split_multiline(content['global']['setup_hooks']) + + for line in setup_hooks: + try: + hook = resolve_name(line) + except ImportError as e: + logger.warning('cannot find setup hook: %s', e.args[0]) + else: + self.setup_hooks.append(hook) + + self.run_hooks(content) metadata = self.dist.metadata diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -90,7 +90,7 @@ compilers = packaging.tests.test_config.DCompiler -setup_hook = %(setup-hook)s +setup_hooks = %(setup-hooks)s @@ -135,8 +135,16 @@ pass -def hook(content): - content['metadata']['version'] += '.dev1' +def version_hook(config): + config['metadata']['version'] += '.dev1' + + +def first_hook(config): + config['files']['modules'] += '\n first' + + +def third_hook(config): + config['files']['modules'] += '\n third' class FooBarBazTest: @@ -186,7 +194,7 @@ def write_setup(self, kwargs=None): opts = {'description-file': 'README', 'extra-files': '', - 'setup-hook': 'packaging.tests.test_config.hook'} + 'setup-hooks': 'packaging.tests.test_config.version_hook'} if kwargs: opts.update(kwargs) self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') @@ -318,13 +326,27 @@ self.assertEqual(ext.extra_compile_args, cargs) self.assertEqual(ext.language, 'cxx') - def test_missing_setuphook_warns(self): - self.write_setup({'setup-hook': 'this.does._not.exist'}) + def test_missing_setup_hook_warns(self): + self.write_setup({'setup-hooks': 'this.does._not.exist'}) self.write_file('README', 'yeah') dist = self.get_dist() logs = self.get_logs(logging.WARNING) self.assertEqual(1, len(logs)) - self.assertIn('could not import setup_hook', logs[0]) + self.assertIn('cannot find setup hook', logs[0]) + + def test_multiple_setup_hooks(self): + self.write_setup({ + 'setup-hooks': '\n packaging.tests.test_config.first_hook' + '\n packaging.tests.test_config.missing_hook' + '\n packaging.tests.test_config.third_hook' + }) + self.write_file('README', 'yeah') + dist = self.get_dist() + + self.assertEqual(['haven', 'first', 'third'], dist.py_modules) + logs = self.get_logs(logging.WARNING) + self.assertEqual(1, len(logs)) + self.assertIn('cannot find setup hook', logs[0]) def test_metadata_requires_description_files_missing(self): self.write_setup({'description-file': 'README README2'}) diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -495,7 +495,7 @@ def test_cfg_to_args(self): opts = {'description-file': 'README', 'extra-files': '', - 'setup-hook': 'packaging.tests.test_config.hook'} + 'setup-hooks': 'packaging.tests.test_config.version_hook'} self.write_file('setup.cfg', SETUP_CFG % opts) self.write_file('README', 'loooong description') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,9 @@ Library ------- +- Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. + Original patch by Erik Bray. + - Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a compatibility helper for the distutils-packaging transition. Original patch by Erik Bray. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:45 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Use_correct_directive_to_do?= =?utf8?q?cument_one_method?= Message-ID: http://hg.python.org/cpython/rev/c16236c00fd8 changeset: 70793:c16236c00fd8 user: ?ric Araujo date: Sat Jun 11 03:27:03 2011 +0200 summary: Use correct directive to document one method files: Doc/library/collections.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -83,7 +83,7 @@ creating subcontexts that can be updated without altering values in any of the parent mappings. - .. attribute:: parents() + .. method:: parents() Returns a new :class:`ChainMap` containing all of the maps in the current instance except the first one. This is useful for skipping the first map -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:45 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Adjust_logging_in_packaging?= =?utf8?q?=2Eutil=2Espawn_=28related_to_=2311599=29?= Message-ID: http://hg.python.org/cpython/rev/3ba34c03f2fc changeset: 70794:3ba34c03f2fc user: ?ric Araujo date: Sat Jun 11 09:46:07 2011 +0200 summary: Adjust logging in packaging.util.spawn (related to #11599) files: Lib/packaging/util.py | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -777,12 +777,13 @@ Raise PackagingExecError if running the program fails in any way; just return on success. """ - logger.info(' '.join(cmd)) + logger.debug('spawn: running %r', cmd) if dry_run: + logging.debug('dry run, no process actually spawned') return exit_status = subprocess.call(cmd, env=env) if exit_status != 0: - msg = "command '%s' failed with exit status %d" + msg = "command %r failed with exit status %d" raise PackagingExecError(msg % (cmd, exit_status)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:46 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Add_missing_reS?= =?utf8?q?T_target_to_one_heading_in_the_tutorial?= Message-ID: http://hg.python.org/cpython/rev/9bfaa723a194 changeset: 70795:9bfaa723a194 branch: 3.2 parent: 70786:1ab1365e6b7a user: ?ric Araujo date: Sat Jun 11 10:34:19 2011 +0200 summary: Add missing reST target to one heading in the tutorial files: Doc/tutorial/interpreter.rst | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -169,6 +169,8 @@ suppressed. +.. _tut-source-encoding: + Source Code Encoding -------------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:47 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Branch_merge?= Message-ID: http://hg.python.org/cpython/rev/0260e3260280 changeset: 70796:0260e3260280 parent: 70788:d0952a2fb7bd parent: 70794:3ba34c03f2fc user: ?ric Araujo date: Sat Jun 11 19:56:09 2011 +0200 summary: Branch merge files: Doc/library/collections.rst | 2 +- Doc/packaging/setupcfg.rst | 15 ++- Lib/packaging/config.py | 69 ++++++++--------- Lib/packaging/tests/test_config.py | 38 +++++++-- Lib/packaging/tests/test_util.py | 48 ++++++++++- Lib/packaging/util.py | 53 +++++++++---- Misc/ACKS | 1 + Misc/NEWS | 7 + 8 files changed, 156 insertions(+), 77 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -83,7 +83,7 @@ creating subcontexts that can be updated without altering values in any of the parent mappings. - .. attribute:: parents() + .. method:: parents() Returns a new :class:`ChainMap` containing all of the maps in the current instance except the first one. This is useful for skipping the first map diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -176,15 +176,19 @@ compilers = hotcompiler.SmartCCompiler -setup_hook - defines a callable that will be called right after the - :file:`setup.cfg` file is read. The callable receives the configuration - in form of a mapping and can make some changes to it. *optional* +setup_hooks + Defines a list of callables to be called right after the :file:`setup.cfg` + file is read, before any other processing. The callables are executed in the + order they're found in the file; if one of them cannot be found, tools should + not stop, but for example produce a warning and continue with the next line. + Each callable receives the configuration as a dictionary (keys are + :file:`setup.cfg` sections, values are dictionaries of fields) and can make + any changes to it. *optional*, *multi* Example:: [global] - setup_hook = package.setup.customize_dist + setup_hooks = package.setup.customize_dist Metadata @@ -285,6 +289,7 @@ description-file Path to a text file that will be used to fill the ``description`` field. + Multiple values are accepted; they must be separated by whitespace. ``description-file`` and ``description`` are mutually exclusive. *optional* diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -9,7 +9,8 @@ from packaging import logger from packaging.errors import PackagingOptionError from packaging.compiler.extension import Extension -from packaging.util import check_environ, iglob, resolve_name, strtobool +from packaging.util import (check_environ, iglob, resolve_name, strtobool, + split_multiline) from packaging.compiler import set_compiler from packaging.command import set_command from packaging.markers import interpret @@ -60,17 +61,15 @@ class Config: - """Reads configuration files and work with the Distribution instance - """ + """Class used to work with configuration files""" def __init__(self, dist): self.dist = dist - self.setup_hook = None + self.setup_hooks = [] - def run_hook(self, config): - if self.setup_hook is None: - return - # the hook gets only the config - self.setup_hook(config) + def run_hooks(self, config): + """Run setup hooks in the order defined in the spec.""" + for hook in self.setup_hooks: + hook(config) def find_config_files(self): """Find as many configuration files as should be processed for this @@ -124,29 +123,26 @@ # XXX return value - def _multiline(self, value): - value = [v for v in - [v.strip() for v in value.split('\n')] - if v != ''] - return value - def _read_setup_cfg(self, parser, cfg_filename): cfg_directory = os.path.dirname(os.path.abspath(cfg_filename)) content = {} for section in parser.sections(): content[section] = dict(parser.items(section)) - # global:setup_hook is called *first* + # global setup hooks are called first if 'global' in content: - if 'setup_hook' in content['global']: - setup_hook = content['global']['setup_hook'] - try: - self.setup_hook = resolve_name(setup_hook) - except ImportError as e: - logger.warning('could not import setup_hook: %s', - e.args[0]) - else: - self.run_hook(content) + if 'setup_hooks' in content['global']: + setup_hooks = split_multiline(content['global']['setup_hooks']) + + for line in setup_hooks: + try: + hook = resolve_name(line) + except ImportError as e: + logger.warning('cannot find setup hook: %s', e.args[0]) + else: + self.setup_hooks.append(hook) + + self.run_hooks(content) metadata = self.dist.metadata @@ -155,7 +151,7 @@ for key, value in content['metadata'].items(): key = key.replace('_', '-') if metadata.is_multi_field(key): - value = self._multiline(value) + value = split_multiline(value) if key == 'project-url': value = [(label.strip(), url.strip()) @@ -168,21 +164,18 @@ "mutually exclusive") raise PackagingOptionError(msg) - if isinstance(value, list): - filenames = value - else: - filenames = value.split() + filenames = value.split() - # concatenate each files - value = '' + # concatenate all files + value = [] for filename in filenames: # will raise if file not found with open(filename) as description_file: - value += description_file.read().strip() + '\n' + value.append(description_file.read().strip()) # add filename as a required file if filename not in metadata.requires_files: metadata.requires_files.append(filename) - value = value.strip() + value = '\n'.join(value).strip() key = 'description' if metadata.is_metadata_field(key): @@ -192,7 +185,7 @@ files = content['files'] self.dist.package_dir = files.pop('packages_root', None) - files = dict((key, self._multiline(value)) for key, value in + files = dict((key, split_multiline(value)) for key, value in files.items()) self.dist.packages = [] @@ -310,7 +303,7 @@ opt = opt.replace('-', '_') if opt == 'sub_commands': - val = self._multiline(val) + val = split_multiline(val) if isinstance(val, str): val = [val] @@ -348,14 +341,14 @@ raise PackagingOptionError(msg) def _load_compilers(self, compilers): - compilers = self._multiline(compilers) + compilers = split_multiline(compilers) if isinstance(compilers, str): compilers = [compilers] for compiler in compilers: set_compiler(compiler.strip()) def _load_commands(self, commands): - commands = self._multiline(commands) + commands = split_multiline(commands) if isinstance(commands, str): commands = [commands] for command in commands: diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -90,7 +90,7 @@ compilers = packaging.tests.test_config.DCompiler -setup_hook = %(setup-hook)s +setup_hooks = %(setup-hooks)s @@ -135,8 +135,16 @@ pass -def hook(content): - content['metadata']['version'] += '.dev1' +def version_hook(config): + config['metadata']['version'] += '.dev1' + + +def first_hook(config): + config['files']['modules'] += '\n first' + + +def third_hook(config): + config['files']['modules'] += '\n third' class FooBarBazTest: @@ -186,7 +194,7 @@ def write_setup(self, kwargs=None): opts = {'description-file': 'README', 'extra-files': '', - 'setup-hook': 'packaging.tests.test_config.hook'} + 'setup-hooks': 'packaging.tests.test_config.version_hook'} if kwargs: opts.update(kwargs) self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') @@ -318,16 +326,30 @@ self.assertEqual(ext.extra_compile_args, cargs) self.assertEqual(ext.language, 'cxx') - def test_missing_setuphook_warns(self): - self.write_setup({'setup-hook': 'this.does._not.exist'}) + def test_missing_setup_hook_warns(self): + self.write_setup({'setup-hooks': 'this.does._not.exist'}) self.write_file('README', 'yeah') dist = self.get_dist() logs = self.get_logs(logging.WARNING) self.assertEqual(1, len(logs)) - self.assertIn('could not import setup_hook', logs[0]) + self.assertIn('cannot find setup hook', logs[0]) + + def test_multiple_setup_hooks(self): + self.write_setup({ + 'setup-hooks': '\n packaging.tests.test_config.first_hook' + '\n packaging.tests.test_config.missing_hook' + '\n packaging.tests.test_config.third_hook' + }) + self.write_file('README', 'yeah') + dist = self.get_dist() + + self.assertEqual(['haven', 'first', 'third'], dist.py_modules) + logs = self.get_logs(logging.WARNING) + self.assertEqual(1, len(logs)) + self.assertIn('cannot find setup hook', logs[0]) def test_metadata_requires_description_files_missing(self): - self.write_setup({'description-file': 'README\n README2'}) + self.write_setup({'description-file': 'README README2'}) self.write_file('README', 'yeah') self.write_file('README2', 'yeah') os.mkdir('src') diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -8,16 +8,18 @@ from io import StringIO from packaging.tests import support, unittest +from packaging.tests.test_config import SETUP_CFG from packaging.errors import ( PackagingPlatformError, PackagingByteCompileError, PackagingFileError, PackagingExecError, InstallationException) from packaging import util +from packaging.dist import Distribution from packaging.util import ( convert_path, change_root, split_quoted, strtobool, rfc822_escape, get_compiler_versions, _MAC_OS_X_LD_VERSION, byte_compile, find_packages, spawn, get_pypirc_path, generate_pypirc, read_pypirc, resolve_name, iglob, RICH_GLOB, egginfo_to_distinfo, is_setuptools, is_distutils, is_packaging, - get_install_method) + get_install_method, cfg_to_args) PYPIRC = """\ @@ -88,13 +90,15 @@ support.LoggingCatcher, unittest.TestCase): - restore_environ = ['HOME'] + restore_environ = ['HOME', 'PLAT'] def setUp(self): super(UtilTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - self.rc = os.path.join(self.tmp_dir, '.pypirc') - os.environ['HOME'] = self.tmp_dir + self.addCleanup(os.chdir, os.getcwd()) + tempdir = self.mkdtemp() + self.rc = os.path.join(tempdir, '.pypirc') + os.environ['HOME'] = tempdir + os.chdir(tempdir) # saving the environment self.name = os.name self.platform = sys.platform @@ -103,7 +107,6 @@ self.join = os.path.join self.isabs = os.path.isabs self.splitdrive = os.path.splitdrive - #self._config_vars = copy(sysconfig._config_vars) # patching os.uname if hasattr(os, 'uname'): @@ -137,7 +140,6 @@ os.uname = self.uname else: del os.uname - #sysconfig._config_vars = copy(self._config_vars) util.find_executable = self.old_find_executable subprocess.Popen = self.old_popen sys.old_stdout = self.old_stdout @@ -491,6 +493,38 @@ content = f.read() self.assertEqual(content, WANTED) + def test_cfg_to_args(self): + opts = {'description-file': 'README', 'extra-files': '', + 'setup-hooks': 'packaging.tests.test_config.version_hook'} + self.write_file('setup.cfg', SETUP_CFG % opts) + self.write_file('README', 'loooong description') + + args = cfg_to_args() + # use Distribution to get the contents of the setup.cfg file + dist = Distribution() + dist.parse_config_files() + metadata = dist.metadata + + self.assertEqual(args['name'], metadata['Name']) + # + .dev1 because the test SETUP_CFG also tests a hook function in + # test_config.py for appending to the version string + self.assertEqual(args['version'] + '.dev1', metadata['Version']) + self.assertEqual(args['author'], metadata['Author']) + self.assertEqual(args['author_email'], metadata['Author-Email']) + self.assertEqual(args['maintainer'], metadata['Maintainer']) + self.assertEqual(args['maintainer_email'], + metadata['Maintainer-Email']) + self.assertEqual(args['description'], metadata['Summary']) + self.assertEqual(args['long_description'], metadata['Description']) + self.assertEqual(args['classifiers'], metadata['Classifier']) + self.assertEqual(args['requires'], metadata['Requires-Dist']) + self.assertEqual(args['provides'], metadata['Provides-Dist']) + + self.assertEqual(args['package_dir'].get(''), dist.package_dir) + self.assertEqual(args['packages'], dist.packages) + self.assertEqual(args['scripts'], dist.scripts) + self.assertEqual(args['py_modules'], dist.py_modules) + class GlobTestCaseBase(support.TempdirManager, support.LoggingCatcher, diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -250,6 +250,14 @@ return words +def split_multiline(value): + """Split a multiline string into a list, excluding blank lines.""" + + return [element for element in + (line.strip() for line in value.split('\n')) + if element] + + def execute(func, args, msg=None, verbose=0, dry_run=False): """Perform some action that affects the outside world. @@ -542,18 +550,15 @@ def _is_package(path): - if not os.path.isdir(path): - return False - return os.path.isfile(os.path.join(path, '__init__.py')) + return os.path.isdir(path) and os.path.isfile( + os.path.join(path, '__init__.py')) # Code taken from the pip project def _is_archive_file(name): archives = ('.zip', '.tar.gz', '.tar.bz2', '.tgz', '.tar') ext = splitext(name)[1].lower() - if ext in archives: - return True - return False + return ext in archives def _under(path, root): @@ -772,12 +777,13 @@ Raise PackagingExecError if running the program fails in any way; just return on success. """ - logger.info(' '.join(cmd)) + logger.debug('spawn: running %r', cmd) if dry_run: + logging.debug('dry run, no process actually spawned') return exit_status = subprocess.call(cmd, env=env) if exit_status != 0: - msg = "command '%s' failed with exit status %d" + msg = "command %r failed with exit status %d" raise PackagingExecError(msg % (cmd, exit_status)) @@ -1010,16 +1016,20 @@ "requires": ("metadata", "requires_dist"), "provides": ("metadata", "provides_dist"), # ** "obsoletes": ("metadata", "obsoletes_dist"), # ** + "package_dir": ("files", 'packages_root'), "packages": ("files",), "scripts": ("files",), "py_modules": ("files", "modules"), # ** } MULTI_FIELDS = ("classifiers", + "platforms", "requires", - "platforms", + "provides", + "obsoletes", "packages", - "scripts") + "scripts", + "py_modules") def has_get_option(config, section, option): if config.has_option(section, option): @@ -1031,9 +1041,9 @@ # The real code starts here config = RawConfigParser() - if not os.path.exists(file): + if not os.path.exists(path): raise PackagingFileError("file '%s' does not exist" % - os.path.abspath(file)) + os.path.abspath(path)) config.read(path) kwargs = {} @@ -1050,17 +1060,24 @@ in_cfg_value = has_get_option(config, section, option) if not in_cfg_value: # There is no such option in the setup.cfg - if arg == "long_description": - filename = has_get_option(config, section, "description_file") - if filename: - with open(filename) as fp: - in_cfg_value = fp.read() + if arg == 'long_description': + filenames = has_get_option(config, section, 'description-file') + if filenames: + filenames = split_multiline(filenames) + in_cfg_value = [] + for filename in filenames: + with open(filename) as fp: + in_cfg_value.append(fp.read()) + in_cfg_value = '\n\n'.join(in_cfg_value) else: continue + if arg == 'package_dir' and in_cfg_value: + in_cfg_value = {'': in_cfg_value} + if arg in MULTI_FIELDS: # support multiline options - in_cfg_value = in_cfg_value.strip().split('\n') + in_cfg_value = split_multiline(in_cfg_value) kwargs[arg] = in_cfg_value diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -116,6 +116,7 @@ Georg Brandl Christopher Brannon Terrence Brannon +Erik Bray Brian Brazil Dave Brennan Tom Bridgman diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -187,6 +187,13 @@ Library ------- +- Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. + Original patch by Erik Bray. + +- Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a + compatibility helper for the distutils-packaging transition. Original patch + by Erik Bray. + - Issue #12287: In ossaudiodev, check that the device isn't closed in several methods. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 20:01:48 2011 From: python-checkins at python.org (eric.araujo) Date: Sat, 11 Jun 2011 20:01:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_minor_doc_change_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/7b02717d5345 changeset: 70797:7b02717d5345 parent: 70796:0260e3260280 parent: 70795:9bfaa723a194 user: ?ric Araujo date: Sat Jun 11 19:56:28 2011 +0200 summary: Merge minor doc change from 3.2 files: Doc/tutorial/interpreter.rst | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -169,6 +169,8 @@ suppressed. +.. _tut-source-encoding: + Source Code Encoding -------------------- -- Repository URL: http://hg.python.org/cpython From tjreedy at udel.edu Sat Jun 11 20:25:40 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 11 Jun 2011 14:25:40 -0400 Subject: [Python-checkins] cpython (3.1): onto 3.1.5 In-Reply-To: References: Message-ID: <4DF3B324.1010708@udel.edu> > +What's New in Python 3.1.5? > +=========================== > + > +*Release date: XXXX-XX-XX* > + > +Core and Builtins > +----------------- > + > +Library > +------- > + > + I presume that only security patches should be added. From benjamin at python.org Sat Jun 11 20:28:16 2011 From: benjamin at python.org (Benjamin Peterson) Date: Sat, 11 Jun 2011 13:28:16 -0500 Subject: [Python-checkins] cpython (3.1): onto 3.1.5 In-Reply-To: <4DF3B324.1010708@udel.edu> References: <4DF3B324.1010708@udel.edu> Message-ID: 2011/6/11 Terry Reedy : > >> +What's New in Python 3.1.5? >> +=========================== >> + >> +*Release date: XXXX-XX-XX* >> + >> +Core and Builtins >> +----------------- >> + >> +Library >> +------- >> + >> + > > I presume that only security patches should be added. Indeed. -- Regards, Benjamin From python-checkins at python.org Sat Jun 11 22:56:15 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 22:56:15 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogYWxsb3cgImZha2Ui?= =?utf8?q?_filenames_in_findsource_=28closes_=239284=29?= Message-ID: http://hg.python.org/cpython/rev/527c40add91d changeset: 70798:527c40add91d branch: 2.7 parent: 70785:35c5d20edb38 user: Benjamin Peterson date: Sat Jun 11 15:53:11 2011 -0500 summary: allow "fake" filenames in findsource (closes #9284) This allows findsource() to work in doctests. A patch from Dirkjan Ochtman. files: Lib/inspect.py | 8 ++++++-- Lib/test/test_inspect.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -524,9 +524,13 @@ or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) - if not file: + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -295,6 +295,23 @@ del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec compile(source, fn, 'single') in ns + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderFile = mod2 diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Library ------- +- Issue #9284: Allow inspect.findsource() to find the source of doctest + functions. + - Issue #10694: zipfile now ignores garbage at the end of a zipfile. - Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 22:56:16 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 22:56:16 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogYWxsb3cgImZha2Ui?= =?utf8?q?_filenames_in_findsource_=28closes_=239284=29?= Message-ID: http://hg.python.org/cpython/rev/6cc4579dca02 changeset: 70799:6cc4579dca02 branch: 3.2 parent: 70795:9bfaa723a194 user: Benjamin Peterson date: Sat Jun 11 15:53:11 2011 -0500 summary: allow "fake" filenames in findsource (closes #9284) This allows findsource() to work in doctests. A patch from Dirkjan Ochtman. files: Lib/inspect.py | 8 ++++++-- Lib/test/test_inspect.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -518,9 +518,13 @@ or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) - if not file: + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -298,6 +298,23 @@ del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec(compile(source, fn, 'single'), ns) + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderModule = mod2 diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -22,6 +22,9 @@ Library ------- +- Issue #9284: Allow inspect.findsource() to find the source of doctest + functions. + - Issue #12009: Fixed regression in netrc file comment handling. - Issue #10694: zipfile now ignores garbage at the end of a zipfile. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 22:56:17 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 22:56:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiBtZXJnZSAzLjIgKCM5Mjg0KQ==?= Message-ID: http://hg.python.org/cpython/rev/f05affb0bb2a changeset: 70800:f05affb0bb2a parent: 70797:7b02717d5345 parent: 70799:6cc4579dca02 user: Benjamin Peterson date: Sat Jun 11 15:56:46 2011 -0500 summary: merge 3.2 (#9284) files: Lib/inspect.py | 8 ++++++-- Lib/test/test_inspect.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -518,9 +518,13 @@ or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) - if not file: + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -298,6 +298,23 @@ del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec(compile(source, fn, 'single'), ns) + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderModule = mod2 diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -190,6 +190,9 @@ - Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. Original patch by Erik Bray. +- Issue #9284: Allow inspect.findsource() to find the source of doctest + functions. + - Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a compatibility helper for the distutils-packaging transition. Original patch by Erik Bray. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 23:11:33 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 23:11:33 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_allow_=5F=5Fdir=5F=5F_to_re?= =?utf8?q?turn_any_sequence?= Message-ID: http://hg.python.org/cpython/rev/f74fceebf853 changeset: 70801:f74fceebf853 user: Benjamin Peterson date: Sat Jun 11 16:12:08 2011 -0500 summary: allow __dir__ to return any sequence files: Doc/reference/datamodel.rst | 3 +- Lib/test/test_builtin.py | 10 +++++- Misc/NEWS | 3 + Objects/object.c | 45 ++++++++---------------- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1343,7 +1343,8 @@ .. method:: object.__dir__(self) - Called when :func:`dir` is called on the object. A list must be returned. + Called when :func:`dir` is called on the object. A sequence must be + returned. :func:`dir` converts the returned sequence to a list and sorts it. .. _descriptors: diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -372,7 +372,15 @@ f = Foo() self.assertTrue(dir(f) == ["ga", "kan", "roo"]) - # dir(obj__dir__not_list) + # dir(obj__dir__tuple) + class Foo(object): + def __dir__(self): + return ("b", "c", "a") + res = dir(Foo()) + self.assertIsInstance(res, list) + self.assertTrue(res == ["a", "b", "c"]) + + # dir(obj__dir__not_sequence) class Foo(object): def __dir__(self): return 7 diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Loosen type restrictions on the __dir__ method. __dir__ can now return any + sequence, which will be converted to a list and sorted by dir(). + - Issue #12265: Make error messages produced by passing an invalid set of arguments to a function more informative. diff --git a/Objects/object.c b/Objects/object.c --- a/Objects/object.c +++ b/Objects/object.c @@ -1205,6 +1205,10 @@ Py_DECREF(names); return NULL; } + if (PyList_Sort(names)) { + Py_DECREF(names); + return NULL; + } /* the locals don't need to be DECREF'd */ return names; } @@ -1213,7 +1217,7 @@ static PyObject * _dir_object(PyObject *obj) { - PyObject *result; + PyObject *result, *sorted; static PyObject *dir_str = NULL; PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str); @@ -1228,18 +1232,16 @@ Py_DECREF(dirfunc); if (result == NULL) return NULL; - - /* result must be a list */ - /* XXX(gbrandl): could also check if all items are strings */ - if (!PyList_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__dir__() must return a list, not %.200s", - Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + /* return sorted(result) */ + sorted = PySequence_List(result); + Py_DECREF(result); + if (sorted == NULL) + return NULL; + if (PyList_Sort(sorted)) { + Py_DECREF(sorted); + return NULL; } - - return result; + return sorted; } /* Implementation of dir() -- if obj is NULL, returns the names in the current @@ -1249,24 +1251,7 @@ PyObject * PyObject_Dir(PyObject *obj) { - PyObject * result; - - if (obj == NULL) - /* no object -- introspect the locals */ - result = _dir_locals(); - else - /* object -- introspect the object */ - result = _dir_object(obj); - - assert(result == NULL || PyList_Check(result)); - - if (result != NULL && PyList_Sort(result) != 0) { - /* sorting the list failed */ - Py_DECREF(result); - result = NULL; - } - - return result; + return (obj == NULL) ? _dir_locals() : _dir_object(obj); } /* -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 11 23:33:00 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 11 Jun 2011 23:33:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_quaint_and_completely_out_o?= =?utf8?q?f_date_comment?= Message-ID: http://hg.python.org/cpython/rev/43605330864b changeset: 70802:43605330864b user: Benjamin Peterson date: Sat Jun 11 16:33:35 2011 -0500 summary: quaint and completely out of date comment files: Objects/object.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Objects/object.c b/Objects/object.c --- a/Objects/object.c +++ b/Objects/object.c @@ -1,5 +1,5 @@ -/* Generic object operations; and implementation of None (NoObject) */ +/* Generic object operations; and implementation of None */ #include "Python.h" #include "frameobject.h" @@ -1255,10 +1255,9 @@ } /* -NoObject is usable as a non-NULL undefined value, used by the macro None. +None is as a non-NULL undefined value. There is (and should be!) no way to create other objects of this type, so there is exactly one (which is indestructible, by the way). -(XXX This type and the type of NotImplemented below should be unified.) */ /* ARGSUSED */ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 12 00:04:43 2011 From: python-checkins at python.org (vinay.sajip) Date: Sun, 12 Jun 2011 00:04:43 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMjA2?= =?utf8?q?=3A_documentation_for_LogRecord_constructor_updated_re=2E_the_le?= =?utf8?q?vel?= Message-ID: http://hg.python.org/cpython/rev/bb6fe43191c0 changeset: 70803:bb6fe43191c0 branch: 3.2 parent: 70799:6cc4579dca02 user: Vinay Sajip date: Sat Jun 11 23:03:37 2011 +0100 summary: Issue #12206: documentation for LogRecord constructor updated re. the level argument. files: Doc/library/logging.rst | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -544,6 +544,9 @@ :param name: The name of the logger used to log the event represented by this LogRecord. :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) + Note that this is converted to *two* attributes of the LogRecord: + ``levelno`` for the numeric value and ``levelname`` for the + corresponding level name. :param pathname: The full pathname of the source file where the logging call was made. :param lineno: The line number in the source file where the logging call was -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 12 00:04:43 2011 From: python-checkins at python.org (vinay.sajip) Date: Sun, 12 Jun 2011 00:04:43 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merged_documentation_update_for_issue_=2312206=2E?= Message-ID: http://hg.python.org/cpython/rev/596adf14914c changeset: 70804:596adf14914c parent: 70802:43605330864b parent: 70803:bb6fe43191c0 user: Vinay Sajip date: Sat Jun 11 23:04:35 2011 +0100 summary: Merged documentation update for issue #12206. files: Doc/library/logging.rst | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -556,6 +556,9 @@ :param name: The name of the logger used to log the event represented by this LogRecord. :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) + Note that this is converted to *two* attributes of the LogRecord: + ``levelno`` for the numeric value and ``levelname`` for the + corresponding level name. :param pathname: The full pathname of the source file where the logging call was made. :param lineno: The line number in the source file where the logging call was -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Sun Jun 12 05:06:21 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 12 Jun 2011 05:06:21 +0200 Subject: [Python-checkins] Daily reference leaks (596adf14914c): sum=399 Message-ID: results for 596adf14914c on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogm6WgMP', '-x'] From python-checkins at python.org Sun Jun 12 12:50:48 2011 From: python-checkins at python.org (vinay.sajip) Date: Sun, 12 Jun 2011 12:50:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Updated_Formatt?= =?utf8?q?er=2EformatTime_documentation=2E?= Message-ID: http://hg.python.org/cpython/rev/7b79bcb9bc89 changeset: 70805:7b79bcb9bc89 branch: 3.2 parent: 70803:bb6fe43191c0 user: Vinay Sajip date: Sun Jun 12 11:44:28 2011 +0100 summary: Updated Formatter.formatTime documentation. files: Doc/library/logging.rst | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -453,6 +453,13 @@ record. Otherwise, the ISO8601 format is used. The resulting string is returned. + This function uses a user-configurable function to convert the creation + time to a tuple. By default, :func:`time.localtime` is used; to change + this for a particular formatter instance, set the ``converter`` attribute + to a function with the same signature as :func:`time.localtime` or + :func:`time.gmtime`. To change it for all formatters, for example if you + want all logging times to be shown in GMT, set the ``converter`` + attribute in the ``Formatter`` class. .. method:: formatException(exc_info) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 12 12:50:49 2011 From: python-checkins at python.org (vinay.sajip) Date: Sun, 12 Jun 2011 12:50:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merged_documentation_update_for_Formatter=2EformatTime=2E?= Message-ID: http://hg.python.org/cpython/rev/67e9ab30f5d3 changeset: 70806:67e9ab30f5d3 parent: 70804:596adf14914c parent: 70805:7b79bcb9bc89 user: Vinay Sajip date: Sun Jun 12 11:50:40 2011 +0100 summary: Merged documentation update for Formatter.formatTime. files: Doc/library/logging.rst | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -453,6 +453,14 @@ record. Otherwise, the ISO8601 format is used. The resulting string is returned. + This function uses a user-configurable function to convert the creation + time to a tuple. By default, :func:`time.localtime` is used; to change + this for a particular formatter instance, set the ``converter`` attribute + to a function with the same signature as :func:`time.localtime` or + :func:`time.gmtime`. To change it for all formatters, for example if you + want all logging times to be shown in GMT, set the ``converter`` + attribute in the ``Formatter`` class. + .. versionchanged:: 3.3 Previously, the default ISO 8601 format was hard-coded as in this example: ``2010-09-06 22:38:15,292`` where the part before the comma is -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Sun Jun 12 15:18:37 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 12 Jun 2011 23:18:37 +1000 Subject: [Python-checkins] cpython (2.7): allow "fake" filenames in findsource (closes #9284) In-Reply-To: References: Message-ID: On Sun, Jun 12, 2011 at 6:56 AM, benjamin.peterson wrote: > summary: > ?allow "fake" filenames in findsource (closes #9284) > > This allows findsource() to work in doctests. > > A patch from Dirkjan Ochtman. Either this exception should be mentioned in the inspect.getsource() documentation or else doctest should be monkeypatching inspect as well as linecache. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From benjamin at python.org Sun Jun 12 17:31:11 2011 From: benjamin at python.org (Benjamin Peterson) Date: Sun, 12 Jun 2011 10:31:11 -0500 Subject: [Python-checkins] cpython (2.7): allow "fake" filenames in findsource (closes #9284) In-Reply-To: References: Message-ID: 2011/6/12 Nick Coghlan : > On Sun, Jun 12, 2011 at 6:56 AM, benjamin.peterson > wrote: >> summary: >> ?allow "fake" filenames in findsource (closes #9284) >> >> This allows findsource() to work in doctests. >> >> A patch from Dirkjan Ochtman. > > Either this exception should be mentioned in the inspect.getsource() > documentation or else doctest should be monkeypatching inspect as well > as linecache. I should have made more clear in the message that this is actually a regression from 2.6. -- Regards, Benjamin From python-checkins at python.org Sun Jun 12 17:37:32 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 12 Jun 2011 17:37:32 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Update_PEP_3150_to_reflect_Apr?= =?utf8?q?il_discussion_on_python-ideas?= Message-ID: http://hg.python.org/peps/rev/854ef904f2c6 changeset: 3885:854ef904f2c6 user: Nick Coghlan date: Mon Jun 13 01:37:12 2011 +1000 summary: Update PEP 3150 to reflect April discussion on python-ideas files: pep-3150.txt | 476 +++++++++++++++++++++++++------------- 1 files changed, 313 insertions(+), 163 deletions(-) diff --git a/pep-3150.txt b/pep-3150.txt --- a/pep-3150.txt +++ b/pep-3150.txt @@ -8,69 +8,67 @@ Content-Type: text/x-rst Created: 2010-07-09 Python-Version: 3.3 -Post-History: 2010-07-14 +Post-History: 2010-07-14, 2011-04-21, 2011-06-13 Resolution: TBD Abstract ======== -A recurring proposal ([1], [2], [3]) on python-ideas is the addition of some form of -statement local namespace. +This PEP proposes the addition of an optional ``given`` clause to several +Python statements that do not currently have an associated code suite. This +clause will create a statement local namespace for additional names that are +accessible in the associated statement, but do not become part of the +containing namespace. -This PEP is intended to serve as a focal point for those ideas, so we -can hopefully avoid retreading the same ground a couple of times a -year. Even if the proposal is never accepted having a PEP to point -people to can be valuable (e.g. having PEP 315 helps greatly in avoiding -endless rehashing of loop-and-a-half arguments). +The primary motivation is to elevate ordinary assignment statements to be +on par with ``class`` and ``def`` statements where the name of the item to +be defined is presented to the reader in advance of the details of how the +value of that item is calculated. -The ideas in this PEP are just a sketch of a way this concept might work. -They avoid some pitfalls that have been encountered in the past, but -have not themselves been subject to the test of implementation. +A secondary motivation is to simplify interim calculations in module and +class level code without polluting the resulting namespaces. + +There are additional emergent properties of the proposed solution which may +be of interest to some users. Most notably, it is proposed that this clause +use a new kind of scope that performs early binding of variables, potentially +replacing other techniques that achieve the same effect (such as the "default +argument hack"). + +The specific proposal in this PEP has been informed by various explorations +of this and related concepts over the years (e.g. [1], [2], [3], [6]). It avoids +some pitfalls that have been encountered in the past, but has not yet itself +been subject to the test of implementation. PEP Deferral ============ -This PEP is currently deferred at least until the language moratorium -(PEP 3003) is officially lifted by Guido. Even after that, it will -require input from at least the four major Python implementations -(CPython, PyPy, Jython, IronPython) on the feasibility of implementing -the proposed semantics to get it moving again. Input from related -projects with a vested interest in Python's syntax (e.g. Cython) will -also be valuable. +Despite the lifting of the language moratorium (PEP 3003) for Python 3.3, +this PEP currently remains in a Deferred state. That means the PEP has to +pass at least *two* hurdles to become part of 3.3. -That said, if a decision on acceptance or rejection had to be made -immediately, rejection would be far more likely. Unlike the previous -major syntax addition to Python (PEP 343's ``with`` statement), this -PEP has no "killer application" of code that is clearly and obviously -improved through the use of the new syntax. The ``with`` statement (in -conjunction with the generator enhancements in PEP 342) allowed -exception handling to be factored out into context managers in a way -that had never before been possible. Code using the new statement was -not only easier to read, but much easier to write correctly in the -first place. +Firstly, I personally have to be sufficiently convinced of the PEP's value and +feasibility to return it to Draft status. While I do see merit in the concept +of statement local namespaces (otherwise I wouldn't have spent so much time +pondering the idea over the years), I also have grave doubts as to the wisdom +of actually adding it to the language (see "Key Concern" below). -In the case of this PEP. however, the "Two Ways to Do It" objection is a -strong one. While the ability to break out subexpresions of a statement -without having to worry about name clashes with the rest of a -function or script and without distracting from the operation that is -the ultimate aim of the statement is potentially nice to have as a -language feature, it doesn't really provide significant expressive power -over and above what is already possible by assigning subexpressions to -ordinary local variables before the statement of interest. In particular, -explaining to new Python programmers when it is best to use a ``given`` -clause and when to use normal local variables is likely to be challenging -and an unnecessary distraction. +Secondly, Guido van Rossum (or his delegate) will need to accept the PEP. At +the very least, that will not occur until a fully functional draft +implementation for CPython is available, and the other three major Python +implementations (PyPy, Jython, IronPython) have indicated that they consider +it feasible to implement the proposed semantics once they reach the point of +targetting 3.3 compatibility. Input from related projects with a vested +interest in Python's syntax (e.g. Cython) will also be valuable. -"It might be kinda, sorta, nice to have, sometimes" really isn't a strong -argument for a new syntactic construct (particularly one this complicated). Proposal ======== This PEP proposes the addition of an optional ``given`` clause to the -syntax for simple statements which may contain an expression. The +syntax for simple statements which may contain an expression, or may +substitute for such an expression for purely syntactic purposes. The current list of simple statements that would be affected by this addition is as follows: @@ -82,88 +80,78 @@ * yield statement * raise statement * assert statement +* pass statement The ``given`` clause would allow subexpressions to be referenced by name in the header line, with the actual definitions following in the indented clause. As a simple example:: c = sqrt(a*a + b*b) given: - a = retrieve_a() - b = retrieve_b() + a, b = 3, 4 + +The ``pass`` statement is included to provide a consistent way to skip +inclusion of a meaningful expression in the header line. While this is not +an intended use case, it isn't one that can be prevented as multiple +alternatives (such as ``...`` and ``()``) remain available even if ``pass`` +itself is disallowed. + Rationale ========= -Some past language features (specifically function decorators -and list comprehensions) were motivated, at least in part, by -the desire to give the important parts of a statement more -prominence when reading code. In the case of function decorators, -information such as whether or not a method is a class or static -method can now be found in the function definition rather than -after the function body. List comprehensions similarly take the -expression being assigned to each member of the list and move it -to the beginning of the expression rather than leaving it buried -inside a ``for`` loop. +Function and class statements in Python have a unique property +relative to ordinary assignment statements: to some degree, they are +*declarative*. They present the reader of the code with some critical +information about a name that is about to be defined, before +proceeding on with the details of the actual definition in the +function or class body. -The rationale for the ``given`` clause is similar. Currently, -breaking out a subexpression requires naming that subexpression -*before* the actual statement of interest. The ``given`` clause -is designed to allow a programmer to highlight for the reader -the statement which is actually of interest (and presumably has -significance for later code) while hiding the most likely irrelevant -"calculation details" inside an indented suite. +The *name* of the object being declared is the first thing stated +after the keyword. Other important information is also given the +honour of preceding the implementation details: -Using the simple example from the proposal section, the current Python -equivalent would be:: +- decorators (which can greatly affect the behaviour of the created + object, and were placed ahead of even the keyword and name as a matter + of practicality moreso than aesthetics) +- the docstring (on the first line immediately following the header line) +- parameters, default values and annotations for function definitions +- parent classes, metaclass and optionally other details (depending on + the metaclass) for class definitions - a = retrieve_a() - b = retrieve_b() - c = sqrt(a*a + b*b) +This PEP proposes to make a similar declarative style available for +arbitrary assignment operations, by permitting the inclusion of a +"given" suite following any simple assignment statement:: -If later code is only interested in the value of c, then the -details involved in retrieving the values of a and b may be an -unnecessary distraction to the reader (particularly if those -details are more complicated than the simple function calls -shown in the example). + TARGET = [TARGET2 = ... TARGETN =] EXPR given: + SUITE -To use a more illustrative example (courtesy of Alex Light), -which of the following is easier to comprehend? +By convention, code in the body of the suite should be oriented solely +towards correctly defining the assignment operation carried out in the +header line. The header line operation should also be adequately +descriptive (e.g. through appropriate choices of variable names) to +give a reader a reasonable idea of the purpose of the operation +without reading the body of the suite. -Subexpressions up front?:: - - sea = water() - temp = get_temperature(sea) - depth = get_depth(sea) - purity = get_purity(sea) - saltiness = get_salinity(sea) - size = get_size(sea) - density = get_density(sea) - desired_property = calc_value(temp, depth, purity, - salinity, size, density) - # Further operations using desired_property - -Or subexpressions indented?:: - - desired_property = calc_value(temp, depth, purity, - salinity, size, density) given: - sea = water() - temp = get_temperature(sea) - depth = get_depth(sea) - purity = get_purity(sea) - saltiness = get_salinity(sea) - size = get_size(sea) - density = get_density(sea) - # Further operations using desired_property +However, while they are the initial motivating use case, limiting this +feature solely to simple assignments would be overly restrictive. Once the +feature is defined at all, it would be quite arbitrary to prevent its use +for augmented assignments, return statements, yield expressions and +arbitrary expressions that may modify the application state. The ``given`` clause may also function as a more readable alternative to some uses of lambda expressions and similar constructs when passing one-off functions to operations -like ``sorted``. +like ``sorted()``. -One way to think of the proposed clause is as a middle -ground between normal in-line code and separation of an +In module and class level code, the ``given`` clause will serve as a +clear and reliable replacement for usage of the ``del`` statement to keep +interim working variables from polluting the resulting namespace. + +One potentially useful way to think of the proposed clause is as a middle +ground between conventional in-line code and separation of an operation out into a dedicated function. + Keyword Choice ============== @@ -185,6 +173,7 @@ statement would look similar but do completely different things. That way lies C++ and Perl :) + Syntax Change ============= @@ -193,6 +182,7 @@ expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) del_stmt: 'del' exprlist + pass_stmt: 'pass' return_stmt: 'return' [testlist] yield_stmt: yield_expr raise_stmt: 'raise' [test ['from' test]] @@ -204,6 +194,7 @@ expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) [given_clause] del_stmt: 'del' exprlist [given_clause] + pass_stmt: 'pass' [given_clause] return_stmt: 'return' [testlist] [given_clause] yield_stmt: yield_expr [given_clause] raise_stmt: 'raise' [test ['from' test]] [given_clause] @@ -218,12 +209,12 @@ an ambiguity in the grammar. It is applied only to the specific elements listed so that nonsense like the following is disallowed:: - pass given: + break given: a = b = 1 -However, even this is inadequate, as it creates problems for the definition -of simple_stmt (which allows chaining of multiple single line statements -with ";" rather than "\\n"). +However, the precise Grammar change described above is inadequate, as it +creates problems for the definition of simple_stmt (which allows chaining of +multiple single line statements with ";" rather than "\\n"). So the above syntax change should instead be taken as a statement of intent. Any actual proposal would need to resolve the simple_stmt parsing problem @@ -234,7 +225,7 @@ a ``given`` clause at the simple_stmt level. Something along the lines of:: stmt: simple_stmt | given_stmt | compound_stmt - simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE + simple_stmt: small_stmt (';' (small_stmt | subexpr_stmt))* [';'] NEWLINE small_stmt: (pass_stmt | flow_stmt | import_stmt | global_stmt | nonlocal_stmt) flow_stmt: break_stmt | continue_stmt @@ -253,54 +244,13 @@ flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt -Common Objections -================= - -* Two Ways To Do It: a lot of code may now be written with values - defined either before the expression where they are used or - afterwards in a ``given`` clause, creating two ways to do it, - without an obvious way of choosing between them. - -* Out of Order Execution: the ``given`` clause makes execution - jump around a little strangely, as the body of the ``given`` - clause is executed before the simple statement in the clause - header. The closest any other part of Python comes to this - is the out of order evaluation in list comprehensions, - generator expressions and conditional expressions. - -These objections should not be dismissed lightly - the proposal -in this PEP needs to be subjected to the test of application to -a large code base (such as the standard library) in a search -for examples where the readability of real world code is genuinely -enhanced. - -New PEP 8 guidelines would also need to be developed to provide -appropriate direction on when to use the ``given`` clause over -ordinary variable assignments. - -Possible Additions -================== - -* The current proposal allows the addition of a ``given`` clause only - for simple statements. Extending the idea to allow the use of - compound statements would be quite possible, but doing so raises - serious readability concerns (as values defined in the ``given`` - clause may be used well before they are defined, exactly the kind - of readability trap that other features like decorators and ``with`` - statements are designed to eliminate) - -* Currently only the outermost clause of comprehensions and generator - expressions can reference the surrounding namespace when executed - at class level. If this proposal is implemented successfully, the - associated namespace semantics could allow that restriction to be - lifted. There would be backwards compatibility implications in doing - so as existing code may be relying on the behaviour of ignoring - class level variables, but the idea is worth considering. +Possible Implementation Strategy +================================ Torture Test -============ +------------ -An implementation of this PEP must support execution of the following +An implementation of this PEP should support execution of the following code at module, class and function scope:: b = {} @@ -341,9 +291,8 @@ >>> b {42: 42} - -Possible Implementation Strategy -================================ +Details of Proposed Semantics +----------------------------- AKA How Class Scopes Screw You When Attempting To Implement This @@ -398,6 +347,175 @@ However, as noted in the abstract, an actual implementation of this idea has never been tried. +Detailed Semantics #1: Early Binding of Variable References +----------------------------------------------------------- + +The copy-in-copy-out semantics mean that all variable references from a +``given`` clause will exhibit early binding behaviour, in contrast to the +late binding typically seen with references to closure variables and globals +in ordinary functions. This behaviour will allow the ``given`` clause to +be used as a substitute for the default argument hack when early binding +behaviour is desired:: + + # Current Python (late binding) + seq = [] + for i in range(10): + def f(): + return i + seq.append(f) + assert seq == [9]*10 + + # Current Python (early binding via default argument hack) + seq = [] + for i in range(10): + def f(_i=i): + return i + seq.append(f) + assert seq == list(range(10)) + + # Early binding via given clause + seq = [] + for i in range(10): + seq.append(f) given: + def f(): + return i + assert seq == list(range(10)) + +Note that the current intention is for the copy-in/copy-out semantics to +apply only to names defined in the local scope containing the ``given`` +clause. Name in outer scopes will be referenced as normal. + +This intention is subject to revision based on feedback and practicalities +of implementation. + +Detailed Semantics #2: Handling of ``nonlocal`` and ``global`` +-------------------------------------------------------------- + +``nonlocal`` and ``global`` will largely operate as if the anonymous +functions were defined as in the expansion above. However, they will also +override the default early-binding semantics from names from the containing +scope. + +This intention is subject to revision based on feedback and practicalities +of implementation. + +Detailed Semantics #3: Handling of ``break`` and ``continue`` +------------------------------------------------------------- + +``break`` and ``continue`` will operate as if the anonymous functions were +defined as in the expansion above. They will be syntax errors if they occur +in the ``given`` clause suite but will work normally if they appear within +a ``for`` or ``while`` loop as part of that suite. + +Detailed Semantics #4: Handling of ``return`` and ``yield`` +------------------------------------------------------------- + +``return`` and ``yield`` are explicitly disallowed in the ``given`` clause +suite and will be syntax errors if they occur. They will work normally if +they appear within a ``def`` statement within that suite. + + +Examples +======== + +Defining "one-off" classes which typically only have a single instance:: + + # Current Python (instantiation after definition) + class public_name(): + ... # However many lines + public_name = public_name(*params) + + # Becomes: + public_name = MeaningfulClassName(*params) given: + class MeaningfulClassName(): + ... # Should trawl the stdlib for an example of doing this + +Calculating attributes without polluting the local namespace (from os.py):: + + # Current Python (manual namespace cleanup) + def _createenviron(): + ... # 27 line function + + environ = _createenviron() + del _createenviron + + # Becomes: + environ = _createenviron() given: + def _createenviron(): + ... # 27 line function + +Replacing default argument hack (from functools.lru_cache):: + + # Current Python (default argument hack) + def decorating_function(user_function, + tuple=tuple, sorted=sorted, len=len, KeyError=KeyError): + ... # 60 line function + return decorating_function + + # Becomes: + return decorating_function given: + # Cell variables rather than locals, but should give similar speedup + tuple, sorted, len, KeyError = tuple, sorted, len, KeyError + def decorating_function(user_function): + ... # 60 line function + + # This example also nicely makes it clear that there is nothing in the + # function after the nested function definition. Due to additional + # nested functions, that isn't entirely clear in the current code. + + +Anticipated Objections +====================== + +* Two Ways To Do It: a lot of code may now be written with values + defined either before the expression where they are used or + afterwards in a ``given`` clause, creating two ways to do it, + without an obvious way of choosing between them. + +* Out of Order Execution: the ``given`` clause makes execution + jump around a little strangely, as the body of the ``given`` + clause is executed before the simple statement in the clause + header. The closest any other part of Python comes to this + is the out of order evaluation in list comprehensions, + generator expressions and conditional expressions. + +* Harmful to Introspection: poking around in module and class internals + is an invaluable tool for white-box testing and interactive debugging. + The ``given`` clause will be quite effective at preventing access to + temporary state used during calculations (although no more so than + current usage of ``del`` statements in that regard) + +These objections should not be dismissed lightly - the proposal +in this PEP needs to be subjected to the test of application to +a large code base (such as the standard library) in a search +for examples where the readability of real world code is genuinely +enhanced. + +New PEP 8 guidelines would also need to be developed to provide +appropriate direction on when to use the ``given`` clause over +ordinary variable assignments. Some thoughts on possible guidelines are +provided at [7] + + +Possible Additions +================== + +* The current proposal allows the addition of a ``given`` clause only + for simple statements. Extending the idea to allow the use of + compound statements would be quite possible, but doing so raises + serious readability concerns (as values defined in the ``given`` + clause may be used well before they are defined, exactly the kind + of readability trap that other features like decorators and ``with`` + statements are designed to eliminate) + +* Currently only the outermost clause of comprehensions and generator + expressions can reference the surrounding namespace when executed + at class level. If this proposal is implemented successfully, the + associated namespace semantics could allow that restriction to be + lifted. There would be backwards compatibility implications in doing + so as existing code may be relying on the behaviour of ignoring + class level variables, but the idea is worth considering. + Reference Implementation ======================== @@ -406,21 +524,47 @@ semantics and code compilation, feel free to try ;) +Key Concern +=========== + +If a decision on the acceptance or rejection of this PEP had to be made +immediately, rejection would be far more likely. Unlike the previous +major syntax addition to Python (PEP 343's ``with`` statement), this +PEP as yet has no "killer application" of common code that is clearly and +obviously improved through the use of the new syntax. The ``with`` statement +(in conjunction with the generator enhancements in PEP 342) allowed +exception handling to be factored out into context managers in a way +that had never before been possible. Code using the new statement was +not only easier to read, but much easier to write correctly in the +first place. + +In the case of this PEP. however, the "Two Ways to Do It" objection is a +strong one. While the ability to break out subexpresions of a statement +without having to worry about name clashes with the rest of a +function or script and without distracting from the operation that is +the ultimate aim of the statement is potentially nice to have as a +language feature, it doesn't really provide significant expressive power +over and above what is already possible by assigning subexpressions to +ordinary local variables before the statement of interest. In particular, +explaining to new Python programmers when it is best to use a ``given`` +clause and when to use normal local variables is likely to be challenging +and an unnecessary distraction. + +"It might be kinda, sorta, nice to have, sometimes" really isn't a strong +argument for a new syntactic construct (particularly one this complicated). +"Status quo wins a stalemate" [5] is a very useful design principle, and I'm +not yet convinced that this PEP clears that hurdle. + +The case for it has definitely strengthened over time though, which is why +this PEP remains Deferred rather than Rejected. + + TO-DO ===== * Mention two-suite in-order variants (and explain why they're even more pointless than the specific idea in the PEP) * Mention PEP 359 and possible uses for locals() in the ``given`` clause -* Define the expected semantics of ``break``, ``continue``, ``return`` - and ``yield`` in a ``given`` clause (i.e. syntax errors at the clause - level, but allowed inside the appropriate compound statements) -* Describe the expected semantics of ``nonlocal`` and ``global`` in the - ``given`` clause. -* Describe the name lookup semantics for function definitions in a - ``given`` clause at function, class and module scope. In particular, - note the early binding effect on loop variables or other variables - that are rebound after the ``given`` clause is complete. References @@ -434,6 +578,12 @@ .. [4] http://mail.python.org/pipermail/python-ideas/2010-July/007596.html +.. [5] http://www.boredomandlaziness.org/2011/02/status-quo-wins-stalemate.html + +.. [6] http://mail.python.org/pipermail/python-ideas/2011-April/009863.html + +.. [7] http://mail.python.org/pipermail/python-ideas/2011-April/009869.html + Copyright ========= -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Sun Jun 12 17:39:32 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 12 Jun 2011 17:39:32 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Add_a_couple_of_missing_Python?= =?utf8?q?_version_headers?= Message-ID: http://hg.python.org/peps/rev/c25fa0913267 changeset: 3886:c25fa0913267 user: Nick Coghlan date: Mon Jun 13 01:39:23 2011 +1000 summary: Add a couple of missing Python version headers files: pep-0342.txt | 1 + pep-0343.txt | 1 + 2 files changed, 2 insertions(+), 0 deletions(-) diff --git a/pep-0342.txt b/pep-0342.txt --- a/pep-0342.txt +++ b/pep-0342.txt @@ -7,6 +7,7 @@ Type: Standards Track Content-Type: text/plain Created: 10-May-2005 +Python-Version: 2.5 Post-History: Introduction diff --git a/pep-0343.txt b/pep-0343.txt --- a/pep-0343.txt +++ b/pep-0343.txt @@ -7,6 +7,7 @@ Type: Standards Track Content-Type: text/plain Created: 13-May-2005 +Python-Version: 2.5 Post-History: 2-Jun-2005, 16-Oct-2005, 29-Oct-2005, 23-Apr-2006, 1-May-2006, 30-Jul-2006 Abstract -- Repository URL: http://hg.python.org/peps From ncoghlan at gmail.com Sun Jun 12 17:55:13 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 13 Jun 2011 01:55:13 +1000 Subject: [Python-checkins] cpython (2.7): allow "fake" filenames in findsource (closes #9284) In-Reply-To: References: Message-ID: On Mon, Jun 13, 2011 at 1:31 AM, Benjamin Peterson wrote: > I should have made more clear in the message that this is actually a > regression from 2.6. Actually looking at the inspect docs, I'm not sure where such a note would fit anyway. I'll think about it a bit more - I have a suspicion there may be a flawed assumption in that inspect code and it should be passing more queries through to linecache rather than trying to second-guess it regarding what source code is available. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Sun Jun 12 22:08:41 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 12 Jun 2011 22:08:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Specify_the_encoding_of_the?= =?utf8?q?_setup=2Ecfg_in_one_packaging_test_=28=2312320=29?= Message-ID: http://hg.python.org/cpython/rev/9eecfeaa591a changeset: 70807:9eecfeaa591a user: ?ric Araujo date: Sun Jun 12 22:04:58 2011 +0200 summary: Specify the encoding of the setup.cfg in one packaging test (#12320) files: Lib/packaging/tests/test_util.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -496,7 +496,7 @@ def test_cfg_to_args(self): opts = {'description-file': 'README', 'extra-files': '', 'setup-hooks': 'packaging.tests.test_config.version_hook'} - self.write_file('setup.cfg', SETUP_CFG % opts) + self.write_file('setup.cfg', SETUP_CFG % opts, encoding='utf-8') self.write_file('README', 'loooong description') args = cfg_to_args() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 12 23:03:11 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 12 Jun 2011 23:03:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Also_specify_encoding_when_?= =?utf8?q?reading_setup=2Ecfg_=28=2312320=29?= Message-ID: http://hg.python.org/cpython/rev/0e22c47b47a3 changeset: 70808:0e22c47b47a3 user: ?ric Araujo date: Sun Jun 12 23:02:57 2011 +0200 summary: Also specify encoding when reading setup.cfg (#12320) files: Lib/packaging/util.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -1044,7 +1044,7 @@ if not os.path.exists(path): raise PackagingFileError("file '%s' does not exist" % os.path.abspath(path)) - config.read(path) + config.read(path, encoding='utf-8') kwargs = {} for arg in D1_D2_SETUP_ARGS: -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Mon Jun 13 05:06:31 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 13 Jun 2011 05:06:31 +0200 Subject: [Python-checkins] Daily reference leaks (0e22c47b47a3): sum=399 Message-ID: results for 0e22c47b47a3 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflog0fWijD', '-x'] From python-checkins at python.org Mon Jun 13 16:00:43 2011 From: python-checkins at python.org (vinay.sajip) Date: Mon, 13 Jun 2011 16:00:43 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Closes_=2312206?= =?utf8?q?=3A_documentation_update_for_LogRecord_constructor_and?= Message-ID: http://hg.python.org/cpython/rev/5fbf0d010276 changeset: 70809:5fbf0d010276 branch: 2.7 parent: 70798:527c40add91d user: Vinay Sajip date: Mon Jun 13 14:59:36 2011 +0100 summary: Closes #12206: documentation update for LogRecord constructor and Formatter.formatTime. files: Doc/library/logging.rst | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -416,6 +416,13 @@ record. Otherwise, the ISO8601 format is used. The resulting string is returned. + This function uses a user-configurable function to convert the creation + time to a tuple. By default, :func:`time.localtime` is used; to change + this for a particular formatter instance, set the ``converter`` attribute + to a function with the same signature as :func:`time.localtime` or + :func:`time.gmtime`. To change it for all formatters, for example if you + want all logging times to be shown in GMT, set the ``converter`` + attribute in the ``Formatter`` class. .. method:: formatException(exc_info) @@ -491,6 +498,9 @@ :param name: The name of the logger used to log the event represented by this LogRecord. :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) + Note that this is converted to *two* attributes of the LogRecord: + ``levelno`` for the numeric value and ``levelname`` for the + corresponding level name. :param pathname: The full pathname of the source file where the logging call was made. :param lineno: The line number in the source file where the logging call was -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 13 16:20:15 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 13 Jun 2011 16:20:15 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312316=3A_Fix_sigwa?= =?utf8?q?it=28=29_test_using_threads?= Message-ID: http://hg.python.org/cpython/rev/d07d0afea9a7 changeset: 70810:d07d0afea9a7 parent: 70808:0e22c47b47a3 user: Victor Stinner date: Mon Jun 13 16:19:06 2011 +0200 summary: Issue #12316: Fix sigwait() test using threads Spawn a new process instead of using fork(). Patch written by Charles-Fran?ois Natali. files: Lib/test/test_signal.py | 68 +++++++++++++++++----------- 1 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -9,6 +9,7 @@ import subprocess import traceback import sys, os, time, errno +from test.script_helper import assert_python_ok try: import threading except ImportError: @@ -598,9 +599,23 @@ with self.assertRaises(ZeroDivisionError): signal.pthread_kill(current, signum) + @unittest.skipUnless(hasattr(signal, 'sigwait'), + 'need signal.sigwait()') @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') - def check_sigwait(self, test, signum): + @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') + def test_sigwait(self): + def test(signum): + signal.alarm(1) + received = signal.sigwait([signum]) + if received != signum: + print("sigwait() received %s, not %s" + % (received, signum), + file=sys.stderr) + os._exit(1) + + signum = signal.SIGALRM + # sigwait must be called with the signal blocked: since the current # process might have several threads running, we fork() a child process # to have a single thread. @@ -627,46 +642,43 @@ else: os._exit(0) else: - # parent: let the child some time to wait, send him the signal, and - # check it correcty received it + # parent: check that the child correcty received the signal self.assertEqual(os.waitpid(pid, 0), (pid, 0)) @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') - def test_sigwait(self): - def test(signum): - signal.alarm(1) - received = signal.sigwait([signum]) - if received != signum: - print("sigwait() received %s, not %s" - % (received, signum), - file=sys.stderr) - os._exit(1) + @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') + @unittest.skipIf(threading is None, "test needs threading module") + def test_sigwait_thread(self): + # Check that calling sigwait() from a thread doesn't suspend the whole + # process. A new interpreter is spawned to avoid problems when mixing + # threads and fork(): only async-safe functions are allowed between + # fork() and exec(). + assert_python_ok("-c", """if True: + import os, threading, sys, time, signal - self.check_sigwait(test, signal.SIGALRM) + # the default handler terminates the process + signum = signal.SIGUSR1 - @unittest.skipUnless(hasattr(signal, 'sigwait'), - 'need signal.sigwait()') - @unittest.skipIf(threading is None, "test needs threading module") - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') - def test_sigwait_thread(self): - def kill_later(signum): - # wait until the main thread is waiting in sigwait() - time.sleep(1) - os.kill(os.getpid(), signum) + def kill_later(): + # wait until the main thread is waiting in sigwait() + time.sleep(1) + os.kill(os.getpid(), signum) - def test(signum): - killer = threading.Thread(target=kill_later, args=(signum,)) + # the signal must be blocked by all the threads + signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + killer = threading.Thread(target=kill_later) killer.start() received = signal.sigwait([signum]) if received != signum: print("sigwait() received %s, not %s" % (received, signum), file=sys.stderr) - os._exit(1) + sys.exit(1) killer.join() - - self.check_sigwait(test, signal.SIGUSR1) + # unblock the signal, which should have been cleared by sigwait() + signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) + """) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 13 18:48:40 2011 From: python-checkins at python.org (barry.warsaw) Date: Mon, 13 Jun 2011 18:48:40 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_PEP_8_updates_on_hanging_conti?= =?utf8?q?nuation_lines=2C_based_on_discussion_from?= Message-ID: http://hg.python.org/peps/rev/00f8e3bb1197 changeset: 3887:00f8e3bb1197 user: Barry Warsaw date: Mon Jun 13 12:48:33 2011 -0400 summary: PEP 8 updates on hanging continuation lines, based on discussion from python-ideas (contributed by Steven Klass). files: pep-0008.txt | 32 +++++++++++++++++++++----------- 1 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pep-0008.txt b/pep-0008.txt --- a/pep-0008.txt +++ b/pep-0008.txt @@ -57,28 +57,38 @@ For really old code that you don't want to mess up, you can continue to use 8-space tabs. - Continuation lines should align wrapped elements either vertically using - Python's implicit line joining inside parentheses, brackets and braces, - or using a hanging indent of double your code indention, in which case - there should be no argument on the first line. For example: + Continuation lines should align wrapped elements either vertically using + Python's implicit line joining inside parentheses, brackets and braces, or + using a hanging indent. When using a hanging indent the following + considerations should be applied; there should be no arguments on the + first line and further indentation should be used to clearly distinguish + itself as a continuation line. Yes: # Aligned with opening delimiter foo = long_function_name(var_one, var_two, var_three, var_four) - # Double code indention for hanging indent; nothing on first line - foo = long_function_name( + # More indentation included to distinguish this from the rest. + def long_function_name( var_one, var_two, var_three, - var_four) + var_four): + print(var_one) - No: # Stuff on first line forbidden + No: # Arguments on first line forbidden when not using vertical alignment foo = long_function_name(var_one, var_two, var_three, var_four) - # 2-space hanging indent forbidden + # Further indentation required as indentation is not distinguishable + def long_function_name( + var_one, var_two, var_three, + var_four): + print(var_one) + + Optional: + # Extra indentation is not necessary. foo = long_function_name( - var_one, var_two, var_three, - var_four) + var_one, var_two, + var_three, var_four) Tabs or Spaces? -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Mon Jun 13 23:10:51 2011 From: python-checkins at python.org (brian.curtin) Date: Mon, 13 Jun 2011 23:10:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogRml4ICMxMjA4NC4g?= =?utf8?q?os=2Estat_on_Windows_wasn=27t_working_properly_with_relative_sym?= =?utf8?q?links=2E?= Message-ID: http://hg.python.org/cpython/rev/1a3e8db28d49 changeset: 70811:1a3e8db28d49 branch: 3.2 parent: 70686:1a1522f612b0 user: Brian Curtin date: Mon Jun 13 15:16:04 2011 -0500 summary: Fix #12084. os.stat on Windows wasn't working properly with relative symlinks. Use of DeviceIoControl to obtain the symlink path via the reparse tag was removed. The code now uses GetFinalPathNameByHandle in the case of a symbolic link and works properly given the added test which creates a symbolic link and calls os.stat on it from multiple locations. Victor Stinner also noticed an issue with os.lstat following the os.stat code path when being passed bytes. The posix_lstat function was adjusted to properly hook up win32_lstat instead of the previous STAT macro (win32_stat). files: Lib/test/support.py | 2 +- Lib/test/test_os.py | 45 +++++ Misc/NEWS | 3 + Modules/posixmodule.c | 241 +++++++++++++++++------------ 4 files changed, 193 insertions(+), 98 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1490,7 +1490,7 @@ try: os.symlink(TESTFN, TESTFN + "can_symlink") can = True - except (OSError, NotImplementedError): + except (OSError, NotImplementedError, AttributeError): can = False _can_symlink = can return can diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1243,6 +1243,51 @@ self.assertEqual(os.stat(link), os.stat(target)) self.assertNotEqual(os.lstat(link), os.stat(link)) + bytes_link = os.fsencode(link) + self.assertEqual(os.stat(bytes_link), os.stat(target)) + self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link)) + + def test_12084(self): + level1 = os.path.abspath(support.TESTFN) + level2 = os.path.join(level1, "level2") + level3 = os.path.join(level2, "level3") + try: + os.mkdir(level1) + os.mkdir(level2) + os.mkdir(level3) + + file1 = os.path.abspath(os.path.join(level1, "file1")) + + with open(file1, "w") as f: + f.write("file1") + + orig_dir = os.getcwd() + try: + os.chdir(level2) + link = os.path.join(level2, "link") + os.symlink(os.path.relpath(file1), "link") + self.assertIn("link", os.listdir(os.getcwd())) + + # Check os.stat calls from the same dir as the link + self.assertEqual(os.stat(file1), os.stat("link")) + + # Check os.stat calls from a dir below the link + os.chdir(level1) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + + # Check os.stat calls from a dir above the link + os.chdir(level3) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + finally: + os.chdir(orig_dir) + except OSError as err: + self.fail(err) + finally: + os.remove(file1) + shutil.rmtree(level1) + class FSEncodingTests(unittest.TestCase): def test_nop(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12084: os.stat on Windows now works properly with relative symbolic + links when called from any directory. + - Issue #1195: my_fgets() now always clears errors before calling fgets(). Fix the following case: sys.stdin.read() stopped with CTRL+d (end of file), raw_input() interrupted by CTRL+c. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -480,14 +480,11 @@ #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int -win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) +win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) { char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; DWORD n_bytes_returned; - const wchar_t *ptr; - wchar_t *buf; - size_t len; if (0 == DeviceIoControl( reparse_point_handle, @@ -496,41 +493,12 @@ target_buffer, sizeof(target_buffer), &n_bytes_returned, NULL)) /* we're not using OVERLAPPED_IO */ - return -1; + return FALSE; if (reparse_tag) *reparse_tag = rdb->ReparseTag; - if (target_path) { - switch (rdb->ReparseTag) { - case IO_REPARSE_TAG_SYMLINK: - /* XXX: Maybe should use SubstituteName? */ - ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); - len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR); - break; - case IO_REPARSE_TAG_MOUNT_POINT: - ptr = rdb->MountPointReparseBuffer.PathBuffer + - rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR); - len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR); - break; - default: - SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */ - return -1; - } - buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1)); - if (!buf) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - wcsncpy(buf, ptr, len); - buf[len] = L'\0'; - if (wcsncmp(buf, L"\\??\\", 4) == 0) - buf[1] = L'\\'; - *target_path = buf; - } - - return 0; + return TRUE; } #endif /* MS_WINDOWS */ @@ -1096,36 +1064,97 @@ return TRUE; } -#ifndef SYMLOOP_MAX -#define SYMLOOP_MAX ( 88 ) -#endif - +/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ +static int has_GetFinalPathNameByHandle = 0; +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, + DWORD); +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, + DWORD); static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth); +check_GetFinalPathNameByHandle() +{ + HINSTANCE hKernel32; + /* only recheck */ + if (!has_GetFinalPathNameByHandle) + { + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleA"); + *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleW"); + has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && + Py_GetFinalPathNameByHandleW; + } + return has_GetFinalPathNameByHandle; +} + +static BOOL +get_target_path(HANDLE hdl, wchar_t **target_path) +{ + int buf_size, result_length; + wchar_t *buf; + + /* We have a good handle to the target, use it to determine + the target path name (then we'll call lstat on it). */ + buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0, + VOLUME_NAME_DOS); + if(!buf_size) + return FALSE; + + buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + result_length = Py_GetFinalPathNameByHandleW(hdl, + buf, buf_size, VOLUME_NAME_DOS); + + if(!result_length) { + free(buf); + return FALSE; + } + + if(!CloseHandle(hdl)) { + free(buf); + return FALSE; + } + + buf[result_length] = 0; + + *target_path = buf; + return TRUE; +} static int -win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth) -{ - int code; - HANDLE hFile; +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse); +static int +win32_xstat_impl(const char *path, struct win32_stat *result, + BOOL traverse) +{ + int code; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const char *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileA( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1149,15 +1178,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileA( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1177,28 +1223,36 @@ } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse) { int code; - HANDLE hFile; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; wchar_t *target_path; const wchar_t *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileW( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1222,15 +1276,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileW( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1254,7 +1325,7 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl(path, result, traverse, 0); + int code = win32_xstat_impl(path, result, traverse); errno = 0; return code; } @@ -1264,13 +1335,11 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl_w(path, result, traverse, 0); + int code = win32_xstat_impl_w(path, result, traverse); errno = 0; return code; } - -/* About the following functions: win32_lstat, win32_lstat_w, win32_stat, - win32_stat_w +/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w In Posix, stat automatically traverses symlinks and returns the stat structure for the target. In Windows, the equivalent GetFileAttributes by @@ -1283,7 +1352,7 @@ The _w represent Unicode equivalents of the aforementioned ANSI functions. */ -static int +static int win32_lstat(const char* path, struct win32_stat *result) { return win32_xstat(path, result, FALSE); @@ -2707,29 +2776,7 @@ return PyBytes_FromString(outbuf); } /* end of posix__getfullpathname */ -/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ -static int has_GetFinalPathNameByHandle = 0; -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, - DWORD); -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, - DWORD); -static int -check_GetFinalPathNameByHandle() -{ - HINSTANCE hKernel32; - /* only recheck */ - if (!has_GetFinalPathNameByHandle) - { - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleA"); - *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleW"); - has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && - Py_GetFinalPathNameByHandleW; - } - return has_GetFinalPathNameByHandle; -} + /* A helper function for samepath on windows */ static PyObject * @@ -5068,7 +5115,7 @@ return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ #ifdef MS_WINDOWS - return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", + return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat", win32_lstat_w); #else return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 13 23:10:52 2011 From: python-checkins at python.org (brian.curtin) Date: Mon, 13 Jun 2011 23:10:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_from_3=2E2_for_Issue_=2312084=2E?= Message-ID: http://hg.python.org/cpython/rev/c04c55afbf81 changeset: 70812:c04c55afbf81 parent: 70688:d8502fee4638 parent: 70811:1a3e8db28d49 user: Brian Curtin date: Mon Jun 13 16:00:35 2011 -0500 summary: Merge from 3.2 for Issue #12084. files: Lib/test/support.py | 2 +- Lib/test/test_os.py | 45 +++++ Misc/NEWS | 3 + Modules/posixmodule.c | 239 +++++++++++++++++------------ 4 files changed, 192 insertions(+), 97 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1562,7 +1562,7 @@ os.symlink(TESTFN, symlink_path) can = True os.remove(symlink_path) - except (OSError, NotImplementedError): + except (OSError, NotImplementedError, AttributeError): can = False _can_symlink = can return can diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1248,6 +1248,51 @@ self.assertEqual(os.stat(link), os.stat(target)) self.assertNotEqual(os.lstat(link), os.stat(link)) + bytes_link = os.fsencode(link) + self.assertEqual(os.stat(bytes_link), os.stat(target)) + self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link)) + + def test_12084(self): + level1 = os.path.abspath(support.TESTFN) + level2 = os.path.join(level1, "level2") + level3 = os.path.join(level2, "level3") + try: + os.mkdir(level1) + os.mkdir(level2) + os.mkdir(level3) + + file1 = os.path.abspath(os.path.join(level1, "file1")) + + with open(file1, "w") as f: + f.write("file1") + + orig_dir = os.getcwd() + try: + os.chdir(level2) + link = os.path.join(level2, "link") + os.symlink(os.path.relpath(file1), "link") + self.assertIn("link", os.listdir(os.getcwd())) + + # Check os.stat calls from the same dir as the link + self.assertEqual(os.stat(file1), os.stat("link")) + + # Check os.stat calls from a dir below the link + os.chdir(level1) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + + # Check os.stat calls from a dir above the link + os.chdir(level3) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + finally: + os.chdir(orig_dir) + except OSError as err: + self.fail(err) + finally: + os.remove(file1) + shutil.rmtree(level1) + class FSEncodingTests(unittest.TestCase): def test_nop(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12084: os.stat on Windows now works properly with relative symbolic + links when called from any directory. + - Issue #12265: Make error messages produced by passing an invalid set of arguments to a function more informative. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -509,14 +509,11 @@ #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int -win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) +win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) { char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; DWORD n_bytes_returned; - const wchar_t *ptr; - wchar_t *buf; - size_t len; if (0 == DeviceIoControl( reparse_point_handle, @@ -525,41 +522,12 @@ target_buffer, sizeof(target_buffer), &n_bytes_returned, NULL)) /* we're not using OVERLAPPED_IO */ - return -1; + return FALSE; if (reparse_tag) *reparse_tag = rdb->ReparseTag; - if (target_path) { - switch (rdb->ReparseTag) { - case IO_REPARSE_TAG_SYMLINK: - /* XXX: Maybe should use SubstituteName? */ - ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); - len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR); - break; - case IO_REPARSE_TAG_MOUNT_POINT: - ptr = rdb->MountPointReparseBuffer.PathBuffer + - rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR); - len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR); - break; - default: - SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */ - return -1; - } - buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1)); - if (!buf) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - wcsncpy(buf, ptr, len); - buf[len] = L'\0'; - if (wcsncmp(buf, L"\\??\\", 4) == 0) - buf[1] = L'\\'; - *target_path = buf; - } - - return 0; + return TRUE; } #endif /* MS_WINDOWS */ @@ -1125,36 +1093,97 @@ return TRUE; } -#ifndef SYMLOOP_MAX -#define SYMLOOP_MAX ( 88 ) -#endif - +/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ +static int has_GetFinalPathNameByHandle = 0; +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, + DWORD); +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, + DWORD); static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth); +check_GetFinalPathNameByHandle() +{ + HINSTANCE hKernel32; + /* only recheck */ + if (!has_GetFinalPathNameByHandle) + { + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleA"); + *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleW"); + has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && + Py_GetFinalPathNameByHandleW; + } + return has_GetFinalPathNameByHandle; +} + +static BOOL +get_target_path(HANDLE hdl, wchar_t **target_path) +{ + int buf_size, result_length; + wchar_t *buf; + + /* We have a good handle to the target, use it to determine + the target path name (then we'll call lstat on it). */ + buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0, + VOLUME_NAME_DOS); + if(!buf_size) + return FALSE; + + buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + result_length = Py_GetFinalPathNameByHandleW(hdl, + buf, buf_size, VOLUME_NAME_DOS); + + if(!result_length) { + free(buf); + return FALSE; + } + + if(!CloseHandle(hdl)) { + free(buf); + return FALSE; + } + + buf[result_length] = 0; + + *target_path = buf; + return TRUE; +} static int -win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth) -{ - int code; - HANDLE hFile; +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse); +static int +win32_xstat_impl(const char *path, struct win32_stat *result, + BOOL traverse) +{ + int code; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const char *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileA( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1178,15 +1207,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileA( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1206,28 +1252,36 @@ } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse) { int code; - HANDLE hFile; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; wchar_t *target_path; const wchar_t *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileW( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1251,15 +1305,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileW( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1283,7 +1354,7 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl(path, result, traverse, 0); + int code = win32_xstat_impl(path, result, traverse); errno = 0; return code; } @@ -1293,13 +1364,11 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl_w(path, result, traverse, 0); + int code = win32_xstat_impl_w(path, result, traverse); errno = 0; return code; } - -/* About the following functions: win32_lstat, win32_lstat_w, win32_stat, - win32_stat_w +/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w In Posix, stat automatically traverses symlinks and returns the stat structure for the target. In Windows, the equivalent GetFileAttributes by @@ -2848,29 +2917,7 @@ return PyBytes_FromString(outbuf); } /* end of posix__getfullpathname */ -/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ -static int has_GetFinalPathNameByHandle = 0; -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, - DWORD); -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, - DWORD); -static int -check_GetFinalPathNameByHandle() -{ - HINSTANCE hKernel32; - /* only recheck */ - if (!has_GetFinalPathNameByHandle) - { - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleA"); - *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleW"); - has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && - Py_GetFinalPathNameByHandleW; - } - return has_GetFinalPathNameByHandle; -} + /* A helper function for samepath on windows */ static PyObject * @@ -5507,7 +5554,7 @@ return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ #ifdef MS_WINDOWS - return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", + return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat", win32_lstat_w); #else return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 13 23:10:53 2011 From: python-checkins at python.org (brian.curtin) Date: Mon, 13 Jun 2011 23:10:53 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_branch_merge?= Message-ID: http://hg.python.org/cpython/rev/b290ca599df6 changeset: 70813:b290ca599df6 parent: 70810:d07d0afea9a7 parent: 70812:c04c55afbf81 user: Brian Curtin date: Mon Jun 13 16:03:01 2011 -0500 summary: branch merge files: Lib/test/support.py | 2 +- Lib/test/test_os.py | 45 +++++ Misc/NEWS | 3 + Modules/posixmodule.c | 239 +++++++++++++++++------------ 4 files changed, 192 insertions(+), 97 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1561,7 +1561,7 @@ try: os.symlink(TESTFN, symlink_path) can = True - except (OSError, NotImplementedError): + except (OSError, NotImplementedError, AttributeError): can = False else: os.remove(symlink_path) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1248,6 +1248,51 @@ self.assertEqual(os.stat(link), os.stat(target)) self.assertNotEqual(os.lstat(link), os.stat(link)) + bytes_link = os.fsencode(link) + self.assertEqual(os.stat(bytes_link), os.stat(target)) + self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link)) + + def test_12084(self): + level1 = os.path.abspath(support.TESTFN) + level2 = os.path.join(level1, "level2") + level3 = os.path.join(level2, "level3") + try: + os.mkdir(level1) + os.mkdir(level2) + os.mkdir(level3) + + file1 = os.path.abspath(os.path.join(level1, "file1")) + + with open(file1, "w") as f: + f.write("file1") + + orig_dir = os.getcwd() + try: + os.chdir(level2) + link = os.path.join(level2, "link") + os.symlink(os.path.relpath(file1), "link") + self.assertIn("link", os.listdir(os.getcwd())) + + # Check os.stat calls from the same dir as the link + self.assertEqual(os.stat(file1), os.stat("link")) + + # Check os.stat calls from a dir below the link + os.chdir(level1) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + + # Check os.stat calls from a dir above the link + os.chdir(level3) + self.assertEqual(os.stat(file1), + os.stat(os.path.relpath(link))) + finally: + os.chdir(orig_dir) + except OSError as err: + self.fail(err) + finally: + os.remove(file1) + shutil.rmtree(level1) + class FSEncodingTests(unittest.TestCase): def test_nop(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12084: os.stat on Windows now works properly with relative symbolic + links when called from any directory. + - Loosen type restrictions on the __dir__ method. __dir__ can now return any sequence, which will be converted to a list and sorted by dir(). diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -509,14 +509,11 @@ #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int -win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) +win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) { char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; DWORD n_bytes_returned; - const wchar_t *ptr; - wchar_t *buf; - size_t len; if (0 == DeviceIoControl( reparse_point_handle, @@ -525,41 +522,12 @@ target_buffer, sizeof(target_buffer), &n_bytes_returned, NULL)) /* we're not using OVERLAPPED_IO */ - return -1; + return FALSE; if (reparse_tag) *reparse_tag = rdb->ReparseTag; - if (target_path) { - switch (rdb->ReparseTag) { - case IO_REPARSE_TAG_SYMLINK: - /* XXX: Maybe should use SubstituteName? */ - ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); - len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR); - break; - case IO_REPARSE_TAG_MOUNT_POINT: - ptr = rdb->MountPointReparseBuffer.PathBuffer + - rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR); - len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR); - break; - default: - SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */ - return -1; - } - buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1)); - if (!buf) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - wcsncpy(buf, ptr, len); - buf[len] = L'\0'; - if (wcsncmp(buf, L"\\??\\", 4) == 0) - buf[1] = L'\\'; - *target_path = buf; - } - - return 0; + return TRUE; } #endif /* MS_WINDOWS */ @@ -1125,36 +1093,97 @@ return TRUE; } -#ifndef SYMLOOP_MAX -#define SYMLOOP_MAX ( 88 ) -#endif - +/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ +static int has_GetFinalPathNameByHandle = 0; +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, + DWORD); +static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, + DWORD); static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth); +check_GetFinalPathNameByHandle() +{ + HINSTANCE hKernel32; + /* only recheck */ + if (!has_GetFinalPathNameByHandle) + { + hKernel32 = GetModuleHandle("KERNEL32"); + *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleA"); + *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, + "GetFinalPathNameByHandleW"); + has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && + Py_GetFinalPathNameByHandleW; + } + return has_GetFinalPathNameByHandle; +} + +static BOOL +get_target_path(HANDLE hdl, wchar_t **target_path) +{ + int buf_size, result_length; + wchar_t *buf; + + /* We have a good handle to the target, use it to determine + the target path name (then we'll call lstat on it). */ + buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0, + VOLUME_NAME_DOS); + if(!buf_size) + return FALSE; + + buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + result_length = Py_GetFinalPathNameByHandleW(hdl, + buf, buf_size, VOLUME_NAME_DOS); + + if(!result_length) { + free(buf); + return FALSE; + } + + if(!CloseHandle(hdl)) { + free(buf); + return FALSE; + } + + buf[result_length] = 0; + + *target_path = buf; + return TRUE; +} static int -win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth) -{ - int code; - HANDLE hFile; +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse); +static int +win32_xstat_impl(const char *path, struct win32_stat *result, + BOOL traverse) +{ + int code; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const char *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileA( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1178,15 +1207,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileA( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1206,28 +1252,36 @@ } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) +win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, + BOOL traverse) { int code; - HANDLE hFile; + HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; wchar_t *target_path; const wchar_t *dot; - if (depth > SYMLOOP_MAX) { - SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ + if(!check_GetFinalPathNameByHandle()) { + /* If the OS doesn't have GetFinalPathNameByHandle, return a + NotImplementedError. */ + PyErr_SetString(PyExc_NotImplementedError, + "GetFinalPathNameByHandle not available on this platform"); return -1; } hFile = CreateFileW( path, - 0, /* desired access */ + FILE_READ_ATTRIBUTES, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ OPEN_EXISTING, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, + /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. + Because of this, calls like GetFinalPathNameByHandle will return + the symlink path agin and not the actual final path. */ + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (hFile == INVALID_HANDLE_VALUE) { @@ -1251,15 +1305,32 @@ } else { if (!GetFileInformationByHandle(hFile, &info)) { CloseHandle(hFile); - return -1;; + return -1; } if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); - CloseHandle(hFile); - if (code < 0) - return code; + if (!win32_get_reparse_tag(hFile, &reparse_tag)) + return -1; + + /* Close the outer open file handle now that we're about to + reopen it with different flags. */ + if (!CloseHandle(hFile)) + return -1; + if (traverse) { - code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); + /* In order to call GetFinalPathNameByHandle we need to open + the file without the reparse handling flag set. */ + hFile2 = CreateFileW( + path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (hFile2 == INVALID_HANDLE_VALUE) + return -1; + + if (!get_target_path(hFile2, &target_path)) + return -1; + + code = win32_xstat_impl_w(target_path, result, FALSE); free(target_path); return code; } @@ -1283,7 +1354,7 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl(path, result, traverse, 0); + int code = win32_xstat_impl(path, result, traverse); errno = 0; return code; } @@ -1293,13 +1364,11 @@ { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ - int code = win32_xstat_impl_w(path, result, traverse, 0); + int code = win32_xstat_impl_w(path, result, traverse); errno = 0; return code; } - -/* About the following functions: win32_lstat, win32_lstat_w, win32_stat, - win32_stat_w +/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w In Posix, stat automatically traverses symlinks and returns the stat structure for the target. In Windows, the equivalent GetFileAttributes by @@ -2848,29 +2917,7 @@ return PyBytes_FromString(outbuf); } /* end of posix__getfullpathname */ -/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ -static int has_GetFinalPathNameByHandle = 0; -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, - DWORD); -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, - DWORD); -static int -check_GetFinalPathNameByHandle() -{ - HINSTANCE hKernel32; - /* only recheck */ - if (!has_GetFinalPathNameByHandle) - { - hKernel32 = GetModuleHandle("KERNEL32"); - *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleA"); - *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleW"); - has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && - Py_GetFinalPathNameByHandleW; - } - return has_GetFinalPathNameByHandle; -} + /* A helper function for samepath on windows */ static PyObject * @@ -5610,7 +5657,7 @@ return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ #ifdef MS_WINDOWS - return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", + return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat", win32_lstat_w); #else return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 13 23:10:54 2011 From: python-checkins at python.org (brian.curtin) Date: Mon, 13 Jun 2011 23:10:54 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_branch_merge=3F?= Message-ID: http://hg.python.org/cpython/rev/4eee3d738d81 changeset: 70814:4eee3d738d81 branch: 3.2 parent: 70811:1a3e8db28d49 parent: 70805:7b79bcb9bc89 user: Brian Curtin date: Mon Jun 13 16:10:32 2011 -0500 summary: branch merge? files: .hgtags | 1 + Doc/c-api/intro.rst | 4 +- Doc/distutils/introduction.rst | 10 +- Doc/documenting/markup.rst | 11 +- Doc/install/index.rst | 15 +- Doc/library/builtins.rst | 4 +- Doc/library/constants.rst | 2 + Doc/library/logging.handlers.rst | 15 ++ Doc/library/logging.rst | 10 + Doc/license.rst | 4 +- Doc/tutorial/interpreter.rst | 2 + Doc/using/cmdline.rst | 2 +- Lib/idlelib/config-main.def | 4 +- Lib/inspect.py | 8 +- Lib/logging/handlers.py | 6 +- Lib/netrc.py | 12 +- Lib/ntpath.py | 11 + Lib/smtplib.py | 2 +- Lib/test/support.py | 5 +- Lib/test/test_inspect.py | 17 ++ Lib/test/test_netrc.py | 131 +++++++++++++----- Lib/test/test_smtplib.py | 15 ++ Lib/test/test_zipfile.py | 18 ++ Lib/zipfile.py | 16 +- Misc/ACKS | 1 + Misc/NEWS | 15 ++ Modules/posixmodule.c | 40 +++++ 27 files changed, 302 insertions(+), 79 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -76,6 +76,7 @@ d18e9d71f369d8211f6ac87252c6d3211f9bd09f v3.1.3rc1 a4f75773c0060cee38b0bb651a7aba6f56b0e996 v3.1.3 32fcb9e94985cb19ce37ba9543f091c0dbe9d7dd v3.1.4rc1 +c918ec9f3a76d6afedfbb5d455004de880443a3d v3.1.4 b37b7834757492d009b99cf0ca4d42d2153d7fac v3.2a1 56d4373cecb73c8b45126ba7b045b3c7b3f94b0b v3.2a2 da012d9a2c23d144e399d2e01a55b8a83ad94573 v3.2a3 diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -588,8 +588,8 @@ Compiling the interpreter with the :c:macro:`Py_DEBUG` macro defined produces what is generally meant by "a debug build" of Python. :c:macro:`Py_DEBUG` is -enabled in the Unix build by adding :option:`--with-pydebug` to the -:file:`configure` command. It is also implied by the presence of the +enabled in the Unix build by adding ``--with-pydebug`` to the +:file:`./configure` command. It is also implied by the presence of the not-Python-specific :c:macro:`_DEBUG` macro. When :c:macro:`Py_DEBUG` is enabled in the Unix build, compiler optimization is disabled. diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -79,11 +79,17 @@ for an example) To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run:: +script, :file:`setup.py`, containing the above code, and run this command from a +terminal:: python setup.py sdist -which will create an archive file (e.g., tarball on Unix, ZIP file on Windows) +For Windows, open a command prompt windows ("DOS box") and change the command +to:: + + setup.py sdist + +:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) containing your setup script :file:`setup.py`, and your module :file:`foo.py`. The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and will unpack into a directory :file:`foo-1.0`. diff --git a/Doc/documenting/markup.rst b/Doc/documenting/markup.rst --- a/Doc/documenting/markup.rst +++ b/Doc/documenting/markup.rst @@ -98,11 +98,12 @@ Spam or ham the foo. -The signatures of object methods or data attributes should always include the -type name (``.. method:: FileInput.input(...)``), even if it is obvious from the -context which type they belong to; this is to enable consistent -cross-references. If you describe methods belonging to an abstract protocol, -such as "context managers", include a (pseudo-)type name too to make the +The signatures of object methods or data attributes should not include the +class name, but be nested in a class directive. The generated files will +reflect this nesting, and the target identifiers (for HTML output) will use +both the class and method name, to enable consistent cross-references. If you +describe methods belonging to an abstract protocol such as context managers, +use a class directive with a (pseudo-)type name too to make the index entries more informative. The directives are: diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -96,10 +96,16 @@ directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the distribution will contain a setup script :file:`setup.py`, and a file named :file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running :: +building and installing the module distribution is a simple matter of running +one command from a terminal:: python setup.py install +For Windows, this command should be run from a command prompt windows ("DOS +box"):: + + setup.py install + If all these things are true, then you already know how to build and install the modules you've just downloaded: Run the command above. Unless you need to install things in a non-standard way or customize the build process, you don't @@ -113,14 +119,11 @@ ========================== As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command:: +distribution using the Distutils is usually one simple command to run from a +terminal:: python setup.py install -On Unix, you'd run this command from a shell prompt; on Windows, you have to -open a command prompt window ("DOS box") and do it there; on Mac OS X, you open -a :command:`Terminal` window to get a shell prompt. - .. _inst-platform-variations: diff --git a/Doc/library/builtins.rst b/Doc/library/builtins.rst --- a/Doc/library/builtins.rst +++ b/Doc/library/builtins.rst @@ -7,7 +7,9 @@ This module provides direct access to all 'built-in' identifiers of Python; for example, ``builtins.open`` is the full name for the built-in function -:func:`open`. +:func:`open`. See :ref:`built-in-funcs` and :ref:`built-in-consts` for +documentation. + This module is not normally accessed explicitly by most applications, but can be useful in modules that provide objects with the same name as a built-in value, diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -1,3 +1,5 @@ +.. _built-in-consts: + Built-in Constants ================== diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -436,6 +436,21 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is *not* sent to the server. + .. versionchanged:: 3.2.1 + (See: :issue:`12168`.) In earlier versions, the message sent to the + syslog daemons was always terminated with a NUL byte, because early + versions of these daemons expected a NUL terminated message - even + though it's not in the relevant specification (RF 5424). More recent + versions of these daemons don't expect the NUL byte but strip it off + if it's there, and even more recent daemons (which adhere more closely + to RFC 5424) pass the NUL byte on as part of the message. + + To enable easier handling of syslog messages in the face of all these + differing daemon behaviours, the appending of the NUL byte has been + made configurable, through the use of a class-level attribute, + ``append_nul``. This defaults to ``True`` (preserving the existing + behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance + in order for that instance to *not* append the NUL terminator. .. method:: encodePriority(facility, priority) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -453,6 +453,13 @@ record. Otherwise, the ISO8601 format is used. The resulting string is returned. + This function uses a user-configurable function to convert the creation + time to a tuple. By default, :func:`time.localtime` is used; to change + this for a particular formatter instance, set the ``converter`` attribute + to a function with the same signature as :func:`time.localtime` or + :func:`time.gmtime`. To change it for all formatters, for example if you + want all logging times to be shown in GMT, set the ``converter`` + attribute in the ``Formatter`` class. .. method:: formatException(exc_info) @@ -544,6 +551,9 @@ :param name: The name of the logger used to log the event represented by this LogRecord. :param level: The numeric level of the logging event (one of DEBUG, INFO etc.) + Note that this is converted to *two* attributes of the LogRecord: + ``levelno`` for the numeric value and ``levelname`` for the + corresponding level name. :param pathname: The full pathname of the source file where the logging call was made. :param lineno: The line number in the source file where the logging call was diff --git a/Doc/license.rst b/Doc/license.rst --- a/Doc/license.rst +++ b/Doc/license.rst @@ -845,7 +845,7 @@ ----- The :mod:`pyexpat` extension is built using an included copy of the expat -sources unless the build is configured :option:`--with-system-expat`:: +sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd and Clark Cooper @@ -874,7 +874,7 @@ ------ The :mod:`_ctypes` extension is built using an included copy of the libffi -sources unless the build is configured :option:`--with-system-libffi`:: +sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -169,6 +169,8 @@ suppressed. +.. _tut-source-encoding: + Source Code Encoding -------------------- diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -501,7 +501,7 @@ ~~~~~~~~~~~~~~~~~~~~ Setting these variables only has an effect in a debug build of Python, that is, -if Python was configured with the :option:`--with-pydebug` build option. +if Python was configured with the ``--with-pydebug`` build option. .. envvar:: PYTHONTHREADDEBUG diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -46,8 +46,8 @@ [General] editor-on-startup= 0 autosave= 0 -print-command-posix=lpr %s -print-command-win=start /min notepad /p %s +print-command-posix=lpr %%s +print-command-win=start /min notepad /p %%s delete-exitfunc= 1 [EditorWindow] diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -518,9 +518,13 @@ or code object. The source code is returned as a list of all the lines in the file and the line number indexes a line in that list. An IOError is raised if the source code cannot be retrieved.""" - file = getsourcefile(object) - if not file: + + file = getfile(object) + sourcefile = getsourcefile(object) + if not sourcefile and file[0] + file[-1] != '<>': raise IOError('source code not available') + file = sourcefile if sourcefile else file + module = getmodule(object, file) if module: lines = linecache.getlines(file, module.__dict__) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -766,6 +766,8 @@ """ return self.priority_map.get(levelName, "warning") + append_nul = True # some old syslog daemons expect a NUL terminator + def emit(self, record): """ Emit a record. @@ -773,7 +775,9 @@ The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) + '\000' + msg = self.format(record) + if self.append_nul: + msg += '\000' """ We need to convert record level to lowercase, maybe this will change in the future. diff --git a/Lib/netrc.py b/Lib/netrc.py --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex +import io, os, shlex __all__ = ["netrc", "NetrcParseError"] @@ -37,12 +37,14 @@ lexer.commenters = lexer.commenters.replace('#', '') while 1: # Look for a machine, default, or macdef top-level keyword + saved_lineno = lexer.lineno toplevel = tt = lexer.get_token() if not tt: break elif tt[0] == '#': - fp.readline(); - continue; + if lexer.lineno == saved_lineno and len(tt) == 1: + lexer.instream.readline() + continue elif tt == 'machine': entryname = lexer.get_token() elif tt == 'default': @@ -68,8 +70,8 @@ self.hosts[entryname] = {} while 1: tt = lexer.get_token() - if (tt=='' or tt == 'machine' or - tt == 'default' or tt =='macdef'): + if (tt.startswith('#') or + tt in {'', 'machine', 'default', 'macdef'}): if password: self.hosts[entryname] = (login, account, password) lexer.push_token(tt) diff --git a/Lib/ntpath.py b/Lib/ntpath.py --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -672,3 +672,14 @@ def sameopenfile(f1, f2): """Test whether two file objects reference the same file""" return _getfileinformation(f1) == _getfileinformation(f2) + + +try: + # The genericpath.isdir implementation uses os.stat and checks the mode + # attribute to tell whether or not the path is a directory. + # This is overkill on Windows - just pass the path to GetFileAttributes + # and check the attribute from there. + from nt import _isdir as isdir +except ImportError: + # Use genericpath.isdir as imported above. + pass diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -162,7 +162,7 @@ re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) def _quote_periods(bindata): - return re.sub(br'(?m)^\.', '..', bindata) + return re.sub(br'(?m)^\.', b'..', bindata) def _fix_eols(data): return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1487,11 +1487,14 @@ global _can_symlink if _can_symlink is not None: return _can_symlink + symlink_path = TESTFN + "can_symlink" try: - os.symlink(TESTFN, TESTFN + "can_symlink") + os.symlink(TESTFN, symlink_path) can = True except (OSError, NotImplementedError, AttributeError): can = False + else: + os.remove(symlink_path) _can_symlink = can return can diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -298,6 +298,23 @@ del sys.modules[name] inspect.getmodule(compile('a=10','','single')) + def test_proceed_with_fake_filename(self): + '''doctest monkeypatches linecache to enable inspection''' + fn, source = '', 'def x(): pass\n' + getlines = linecache.getlines + def monkey(filename, module_globals=None): + if filename == fn: + return source.splitlines(True) + else: + return getlines(filename, module_globals) + linecache.getlines = monkey + try: + ns = {} + exec(compile(source, fn, 'single'), ns) + inspect.getsource(ns["x"]) + finally: + linecache.getlines = getlines + class TestDecorators(GetSourceBase): fodderModule = mod2 diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,54 +1,107 @@ - -import netrc, os, unittest, sys +import netrc, os, unittest, sys, textwrap from test import support -TEST_NETRC = """ - - #this is a comment -#this is a comment -# this is a comment - -machine foo login log1 password pass1 account acct1 -machine bar login log1 password pass# account acct1 - -macdef macro1 -line1 -line2 - -macdef macro2 -line3 -line4 - -default login log2 password pass2 - -""" - temp_filename = support.TESTFN class NetrcTestCase(unittest.TestCase): - def setUp(self): - mode = 'w' - if sys.platform not in ['cygwin']: - mode += 't' - fp = open(temp_filename, mode) - fp.write(TEST_NETRC) - fp.close() - self.nrc = netrc.netrc(temp_filename) - def tearDown(self): os.unlink(temp_filename) - def test_case_1(self): - self.assertEqual(self.nrc.hosts['foo'], ('log1', 'acct1', 'pass1')) - self.assertEqual(self.nrc.hosts['default'], ('log2', None, 'pass2')) + def make_nrc(self, test_data): + test_data = textwrap.dedent(test_data) + mode = 'w' + if sys.platform != 'cygwin': + mode += 't' + with open(temp_filename, mode) as fp: + fp.write(test_data) + return netrc.netrc(temp_filename) + + def test_default(self): + nrc = self.make_nrc("""\ + machine host1.domain.com login log1 password pass1 account acct1 + default login log2 password pass2 + """) + self.assertEqual(nrc.hosts['host1.domain.com'], + ('log1', 'acct1', 'pass1')) + self.assertEqual(nrc.hosts['default'], ('log2', None, 'pass2')) def test_macros(self): - self.assertEqual(self.nrc.macros, {'macro1':['line1\n', 'line2\n'], - 'macro2':['line3\n', 'line4\n']}) + nrc = self.make_nrc("""\ + macdef macro1 + line1 + line2 - def test_parses_passwords_with_hash_character(self): - self.assertEqual(self.nrc.hosts['bar'], ('log1', 'acct1', 'pass#')) + macdef macro2 + line3 + line4 + """) + self.assertEqual(nrc.macros, {'macro1': ['line1\n', 'line2\n'], + 'macro2': ['line3\n', 'line4\n']}) + + def _test_passwords(self, nrc, passwd): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['host.domain.com'], ('log', 'acct', passwd)) + + def test_password_with_leading_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password #pass account acct + """, '#pass') + + def test_password_with_trailing_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pass# account acct + """, 'pass#') + + def test_password_with_internal_hash(self): + self._test_passwords("""\ + machine host.domain.com login log password pa#ss account acct + """, 'pa#ss') + + def _test_comment(self, nrc, passwd='pass'): + nrc = self.make_nrc(nrc) + self.assertEqual(nrc.hosts['foo.domain.com'], ('bar', None, passwd)) + self.assertEqual(nrc.hosts['bar.domain.com'], ('foo', None, 'pass')) + + def test_comment_before_machine_line(self): + self._test_comment("""\ + # comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_no_space(self): + self._test_comment("""\ + #comment + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_before_machine_line_hash_only(self): + self._test_comment("""\ + # + machine foo.domain.com login bar password pass + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass # comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_no_space(self): + self._test_comment("""\ + machine foo.domain.com login bar password pass #comment + machine bar.domain.com login foo password pass + """) + + def test_comment_at_end_of_machine_line_pass_has_hash(self): + self._test_comment("""\ + machine foo.domain.com login bar password #pass #comment + machine bar.domain.com login foo password pass + """, '#pass') + def test_main(): support.run_unittest(NetrcTestCase) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -278,6 +278,21 @@ mexpect = '%s%s\n%s' % (MSG_BEGIN, m.decode('ascii'), MSG_END) self.assertEqual(self.output.getvalue(), mexpect) + def testSendNeedingDotQuote(self): + # Issue 12283 + m = '.A test\n.mes.sage.' + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) + smtp.sendmail('John', 'Sally', m) + # XXX (see comment in testSend) + time.sleep(0.01) + smtp.quit() + + self.client_evt.set() + self.serv_evt.wait() + self.output.flush() + mexpect = '%s%s\n%s' % (MSG_BEGIN, m, MSG_END) + self.assertEqual(self.output.getvalue(), mexpect) + def testSendMessage(self): m = email.mime.text.MIMEText('A test message') smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3) diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -351,6 +351,24 @@ with zipfile.ZipFile(f, "r") as zipfp: self.assertEqual(zipfp.namelist(), [TESTFN]) + def test_ignores_newline_at_end(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("\r\n\00\00\00") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + + def test_ignores_stuff_appended_past_comments(self): + with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: + zipfp.comment = b"this is a comment" + zipfp.write(TESTFN, TESTFN) + with open(TESTFN2, 'a') as f: + f.write("abcdef\r\n") + with zipfile.ZipFile(TESTFN2, "r") as zipfp: + self.assertIsInstance(zipfp, zipfile.ZipFile) + self.assertEqual(zipfp.comment, b"this is a comment") + def test_write_default_name(self): """Check that calling ZipFile.write without arcname specified produces the expected result.""" diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -246,16 +246,14 @@ # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] endrec = list(struct.unpack(structEndArchive, recData)) - comment = data[start+sizeEndCentDir:] - # check that comment length is correct - if endrec[_ECD_COMMENT_SIZE] == len(comment): - # Append the archive comment and start offset - endrec.append(comment) - endrec.append(maxCommentStart + start) + commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file + comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] + endrec.append(comment) + endrec.append(maxCommentStart + start) - # Try to read the "Zip64 end of central directory" structure - return _EndRecData64(fpin, maxCommentStart + start - filesize, - endrec) + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) # Unable to find a valid end of central directory structure return diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -609,6 +609,7 @@ James A Morrison Pablo Mouzo Mher Movsisyan +Ruslan Mstoi Sjoerd Mullender Sape Mullender Michael Muller diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,21 @@ Library ------- +- Issue #9284: Allow inspect.findsource() to find the source of doctest + functions. + +- Issue #12009: Fixed regression in netrc file comment handling. + +- Issue #10694: zipfile now ignores garbage at the end of a zipfile. + +- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. + +- Issue #12168: SysLogHandler now allows NUL termination to be controlled using + a new 'append_nul' attribute on the handler. + +- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes + instead of os.stat. + - Named tuples now work correctly with vars(). - Issue #12085: Fix an attribute error in subprocess.Popen destructor if the diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2866,6 +2866,45 @@ info.nFileIndexHigh, info.nFileIndexLow); } + +PyDoc_STRVAR(posix__isdir__doc__, +"Return true if the pathname refers to an existing directory."); + +static PyObject * +posix__isdir(PyObject *self, PyObject *args) +{ + PyObject *opath; + char *path; + PyUnicodeObject *po; + DWORD attributes; + + if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { + Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); + + attributes = GetFileAttributesW(wpath); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + goto check; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + + if (!PyArg_ParseTuple(args, "O&:_isdir", + PyUnicode_FSConverter, &opath)) + return NULL; + + path = PyBytes_AsString(opath); + attributes = GetFileAttributesA(path); + if (attributes == INVALID_FILE_ATTRIBUTES) + Py_RETURN_FALSE; + +check: + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; +} #endif /* MS_WINDOWS */ PyDoc_STRVAR(posix_mkdir__doc__, @@ -8102,6 +8141,7 @@ {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, + {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, #endif #ifdef HAVE_GETLOADAVG {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Tue Jun 14 05:07:01 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 14 Jun 2011 05:07:01 +0200 Subject: [Python-checkins] Daily reference leaks (b290ca599df6): sum=399 Message-ID: results for b290ca599df6 on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/refloghNrhjg', '-x'] From python-checkins at python.org Tue Jun 14 17:06:50 2011 From: python-checkins at python.org (brian.curtin) Date: Tue, 14 Jun 2011 17:06:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Correct_complet?= =?utf8?q?ely_broken_os=2Estat_behavior_on_Windows_XP=2E?= Message-ID: http://hg.python.org/cpython/rev/1524a60016d0 changeset: 70815:1524a60016d0 branch: 3.2 user: Brian Curtin date: Tue Jun 14 09:52:50 2011 -0500 summary: Correct completely broken os.stat behavior on Windows XP. After 1a3e8db28d49, Windows XP could not os.stat at all due to raising immediately when GetFinalPathNameByHandle wasn't available (pre-Vista). The proper behavior in that situation is to just not attempt a traversal rather than outright rejecting. This change additionally handles a failed malloc by setting the error code and returning false. Patch by Hirokazu Yamamoto. files: Modules/posixmodule.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1102,6 +1102,11 @@ return FALSE; buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + if (!buf) { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + result_length = Py_GetFinalPathNameByHandleW(hdl, buf, buf_size, VOLUME_NAME_DOS); @@ -1136,11 +1141,9 @@ const char *dot; if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, return a - NotImplementedError. */ - PyErr_SetString(PyExc_NotImplementedError, - "GetFinalPathNameByHandle not available on this platform"); - return -1; + /* If the OS doesn't have GetFinalPathNameByHandle, don't + traverse reparse point. */ + traverse = FALSE; } hFile = CreateFileA( @@ -1234,11 +1237,9 @@ const wchar_t *dot; if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, return a - NotImplementedError. */ - PyErr_SetString(PyExc_NotImplementedError, - "GetFinalPathNameByHandle not available on this platform"); - return -1; + /* If the OS doesn't have GetFinalPathNameByHandle, don't + traverse reparse point. */ + traverse = FALSE; } hFile = CreateFileW( -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 14 17:06:51 2011 From: python-checkins at python.org (brian.curtin) Date: Tue, 14 Jun 2011 17:06:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_3=2E2_-_update_to_the_fix_for_=2312084?= Message-ID: http://hg.python.org/cpython/rev/23e14af406df changeset: 70816:23e14af406df parent: 70813:b290ca599df6 parent: 70815:1524a60016d0 user: Brian Curtin date: Tue Jun 14 10:06:41 2011 -0500 summary: Merge 3.2 - update to the fix for #12084 files: Modules/posixmodule.c | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1131,6 +1131,11 @@ return FALSE; buf = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); + if (!buf) { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + result_length = Py_GetFinalPathNameByHandleW(hdl, buf, buf_size, VOLUME_NAME_DOS); @@ -1165,11 +1170,9 @@ const char *dot; if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, return a - NotImplementedError. */ - PyErr_SetString(PyExc_NotImplementedError, - "GetFinalPathNameByHandle not available on this platform"); - return -1; + /* If the OS doesn't have GetFinalPathNameByHandle, don't + traverse reparse point. */ + traverse = FALSE; } hFile = CreateFileA( @@ -1263,11 +1266,9 @@ const wchar_t *dot; if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, return a - NotImplementedError. */ - PyErr_SetString(PyExc_NotImplementedError, - "GetFinalPathNameByHandle not available on this platform"); - return -1; + /* If the OS doesn't have GetFinalPathNameByHandle, don't + traverse reparse point. */ + traverse = FALSE; } hFile = CreateFileW( -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 14 21:09:28 2011 From: python-checkins at python.org (georg.brandl) Date: Tue, 14 Jun 2011 21:09:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_markup=2E?= Message-ID: http://hg.python.org/cpython/rev/dd775b1561ba changeset: 70817:dd775b1561ba user: Georg Brandl date: Tue Jun 14 21:09:55 2011 +0200 summary: Fix markup. files: Doc/library/logging.rst | 22 +++++++++++----------- 1 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -462,17 +462,17 @@ attribute in the ``Formatter`` class. .. versionchanged:: 3.3 - Previously, the default ISO 8601 format was hard-coded as in this - example: ``2010-09-06 22:38:15,292`` where the part before the comma is - handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the - part after the comma is a millisecond value. Because strptime does not - have a format placeholder for milliseconds, the millisecond value is - appended using another format string, ``'%s,%03d'`` ? and both of these - format strings have been hardcoded into this method. With the change, - these strings are defined as class-level attributes which can be - overridden at the instance level when desired. The names of the - attributes are ``default_time_format`` (for the strptime format string) - and ``default_msec_format`` (for appending the millisecond value). + Previously, the default ISO 8601 format was hard-coded as in this + example: ``2010-09-06 22:38:15,292`` where the part before the comma is + handled by a strptime format string (``'%Y-%m-%d %H:%M:%S'``), and the + part after the comma is a millisecond value. Because strptime does not + have a format placeholder for milliseconds, the millisecond value is + appended using another format string, ``'%s,%03d'`` ? and both of these + format strings have been hardcoded into this method. With the change, + these strings are defined as class-level attributes which can be + overridden at the instance level when desired. The names of the + attributes are ``default_time_format`` (for the strptime format string) + and ``default_msec_format`` (for appending the millisecond value). .. method:: formatException(exc_info) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 14 22:52:09 2011 From: python-checkins at python.org (barry.warsaw) Date: Tue, 14 Jun 2011 22:52:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Make_sure_all_the_Lib/packa?= =?utf8?q?ging_subdirectories_get_installed=2E?= Message-ID: http://hg.python.org/cpython/rev/26a2c6afcc5d changeset: 70818:26a2c6afcc5d user: Barry Warsaw date: Tue Jun 14 16:51:58 2011 -0400 summary: Make sure all the Lib/packaging subdirectories get installed. files: Makefile.pre.in | 56 +++++++++++++++++++++++++++++++++++- 1 files changed, 54 insertions(+), 2 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -912,7 +912,8 @@ XMLLIBSUBDIRS= xml xml/dom xml/etree xml/parsers xml/sax LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ tkinter/test/test_ttk site-packages test \ - test/cjkencodings test/decimaltestdata test/xmltestdata test/subprocessdata \ + test/cjkencodings test/decimaltestdata test/xmltestdata \ + test/subprocessdata \ test/tracedmodules test/encoded_modules \ collections concurrent concurrent/futures encodings \ email email/mime email/test email/test/data \ @@ -920,12 +921,63 @@ sqlite3 sqlite3/test \ logging csv wsgiref urllib \ lib2to3 lib2to3/fixes lib2to3/pgen2 lib2to3/tests \ - lib2to3/tests/data lib2to3/tests/data/fixers lib2to3/tests/data/fixers/myfixes \ + lib2to3/tests/data lib2to3/tests/data/fixers \ + lib2to3/tests/data/fixers/myfixes \ ctypes ctypes/test ctypes/macholib idlelib idlelib/Icons \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ importlib importlib/test importlib/test/builtin \ importlib/test/extension importlib/test/frozen \ importlib/test/import_ importlib/test/source \ + packaging packaging/command packaging/compiler \ + packaging/pypi packaging/tests \ + packaging/tests/fake_dists \ + packaging/tests/fake_dists/babar-0.1.dist-info \ + packaging/tests/fake_dists/bacon-0.1.egg-info \ + packaging/tests/fake_dists/banana-0.4.egg \ + packaging/tests/fake_dists/banana-0.4.egg/EGG-INFO \ + packaging/tests/fake_dists/choxie-2.0.0.9 \ + packaging/tests/fake_dists/choxie-2.0.0.9/choxie \ + packaging/tests/fake_dists/choxie-2.0.0.9.dist-info \ + packaging/tests/fake_dists/coconuts-aster-10.3.egg-info \ + packaging/tests/fake_dists/grammar-1.0a4 \ + packaging/tests/fake_dists/grammar-1.0a4.dist-info \ + packaging/tests/fake_dists/grammar-1.0a4/grammar \ + packaging/tests/fake_dists/towel_stuff-0.1 \ + packaging/tests/fake_dists/towel_stuff-0.1.dist-info \ + packaging/tests/fake_dists/towel_stuff-0.1/towel_stuff \ + packaging/tests/fixer packaging/tests/pypiserver \ + packaging/tests/pypiserver/downloads_with_md5 \ + packaging/tests/pypiserver/downloads_with_md5/packages \ + packaging/tests/pypiserver/downloads_with_md5/packages/source \ + packaging/tests/pypiserver/downloads_with_md5/packages/source/f \ + packaging/tests/pypiserver/downloads_with_md5/packages/source/f/foobar \ + packaging/tests/pypiserver/downloads_with_md5/simple \ + packaging/tests/pypiserver/downloads_with_md5/simple/badmd5 \ + packaging/tests/pypiserver/downloads_with_md5/simple/foobar \ + packaging/tests/pypiserver/foo_bar_baz \ + packaging/tests/pypiserver/foo_bar_baz/simple \ + packaging/tests/pypiserver/foo_bar_baz/simple/bar \ + packaging/tests/pypiserver/foo_bar_baz/simple/baz \ + packaging/tests/pypiserver/foo_bar_baz/simple/foo \ + packaging/tests/pypiserver/project_list \ + packaging/tests/pypiserver/project_list/simple \ + packaging/tests/pypiserver/test_found_links \ + packaging/tests/pypiserver/test_found_links/simple \ + packaging/tests/pypiserver/test_found_links/simple/foobar \ + packaging/tests/pypiserver/test_pypi_server \ + packaging/tests/pypiserver/test_pypi_server/external \ + packaging/tests/pypiserver/test_pypi_server/simple \ + packaging/tests/pypiserver/with_externals \ + packaging/tests/pypiserver/with_externals/external \ + packaging/tests/pypiserver/with_externals/simple \ + packaging/tests/pypiserver/with_externals/simple/foobar \ + packaging/tests/pypiserver/with_norel_links \ + packaging/tests/pypiserver/with_norel_links/external \ + packaging/tests/pypiserver/with_norel_links/simple \ + packaging/tests/pypiserver/with_norel_links/simple/foobar \ + packaging/tests/pypiserver/with_real_externals \ + packaging/tests/pypiserver/with_real_externals/simple \ + packaging/tests/pypiserver/with_real_externals/simple/foobar \ turtledemo \ multiprocessing multiprocessing/dummy \ unittest unittest/test \ -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Wed Jun 15 05:05:38 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 15 Jun 2011 05:05:38 +0200 Subject: [Python-checkins] Daily reference leaks (26a2c6afcc5d): sum=399 Message-ID: results for 26a2c6afcc5d on branch "default" -------------------------------------------- test_packaging leaked [133, 133, 133] references, sum=399 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogBgDsBf', '-x'] From python-checkins at python.org Wed Jun 15 17:52:57 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 15 Jun 2011 17:52:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Minor_wording_i?= =?utf8?q?mprovement?= Message-ID: http://hg.python.org/cpython/rev/8a9d25804c3d changeset: 70819:8a9d25804c3d branch: 3.2 parent: 70815:1524a60016d0 user: ?ric Araujo date: Wed Jun 15 17:49:20 2011 +0200 summary: Minor wording improvement files: Doc/library/abc.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -11,8 +11,8 @@ -------------- -This module provides the infrastructure for defining an :term:`abstract base -class` (ABC) in Python, as outlined in :pep:`3119`; see the PEP for why this +This module provides the infrastructure for defining :term:`abstract base +classes ` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this was added to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 15 17:52:58 2011 From: python-checkins at python.org (eric.araujo) Date: Wed, 15 Jun 2011 17:52:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_wording_change_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/39db4d8c6335 changeset: 70820:39db4d8c6335 parent: 70818:26a2c6afcc5d parent: 70819:8a9d25804c3d user: ?ric Araujo date: Wed Jun 15 17:51:05 2011 +0200 summary: Merge wording change from 3.2 files: Doc/library/abc.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -11,8 +11,8 @@ -------------- -This module provides the infrastructure for defining an :term:`abstract base -class` (ABC) in Python, as outlined in :pep:`3119`; see the PEP for why this +This module provides the infrastructure for defining :term:`abstract base +classes ` (ABCs) in Python, as outlined in :pep:`3119`; see the PEP for why this was added to Python. (See also :pep:`3141` and the :mod:`numbers` module regarding a type hierarchy for numbers based on ABCs.) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 16 00:01:06 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 16 Jun 2011 00:01:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312167=3A_Fix_a_rea?= =?utf8?q?fleak_in_packaging=2Etests=2EPyPIServer_constructor?= Message-ID: http://hg.python.org/cpython/rev/fd6446a88fe3 changeset: 70821:fd6446a88fe3 user: Victor Stinner date: Wed Jun 15 23:58:57 2011 +0200 summary: Issue #12167: Fix a reafleak in packaging.tests.PyPIServer constructor Don't modify mutable default arguments... files: Lib/packaging/tests/pypi_server.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/pypi_server.py b/Lib/packaging/tests/pypi_server.py --- a/Lib/packaging/tests/pypi_server.py +++ b/Lib/packaging/tests/pypi_server.py @@ -88,7 +88,7 @@ """ def __init__(self, test_static_path=None, - static_filesystem_paths=["default"], + static_filesystem_paths=None, static_uri_paths=["simple", "packages"], serve_xmlrpc=False): """Initialize the server. @@ -105,6 +105,8 @@ threading.Thread.__init__(self) self._run = True self._serve_xmlrpc = serve_xmlrpc + if static_filesystem_paths is None: + static_filesystem_paths = ["default"] #TODO allow to serve XMLRPC and HTTP static files at the same time. if not self._serve_xmlrpc: -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Thu Jun 16 05:05:58 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 16 Jun 2011 05:05:58 +0200 Subject: [Python-checkins] Daily reference leaks (fd6446a88fe3): sum=351 Message-ID: results for fd6446a88fe3 on branch "default" -------------------------------------------- test_packaging leaked [117, 117, 117] references, sum=351 test_pydoc leaked [0, -323, 323] references, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogArnaFp', '-x'] From python-checkins at python.org Thu Jun 16 23:33:29 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 16 Jun 2011 23:33:29 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogRml4IHR5cG8u?= Message-ID: http://hg.python.org/cpython/rev/0fe3b81c7c89 changeset: 70822:0fe3b81c7c89 branch: 3.2 parent: 70819:8a9d25804c3d user: Raymond Hettinger date: Thu Jun 16 22:32:10 2011 +0100 summary: Fix typo. files: Doc/whatsnew/3.2.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -385,7 +385,7 @@ ===================================================== This informational PEP clarifies how bytes/text issues are to be handled by the -WGSI protocol. The challenge is that string handling in Python 3 is most +WSGI protocol. The challenge is that string handling in Python 3 is most conveniently handled with the :class:`str` type even though the HTTP protocol is itself bytes oriented. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 16 23:33:30 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 16 Jun 2011 23:33:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Fix_typo=2E?= Message-ID: http://hg.python.org/cpython/rev/cf56abd14eef changeset: 70823:cf56abd14eef parent: 70821:fd6446a88fe3 parent: 70822:0fe3b81c7c89 user: Raymond Hettinger date: Thu Jun 16 22:33:20 2011 +0100 summary: Fix typo. files: Doc/whatsnew/3.2.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -385,7 +385,7 @@ ===================================================== This informational PEP clarifies how bytes/text issues are to be handled by the -WGSI protocol. The challenge is that string handling in Python 3 is most +WSGI protocol. The challenge is that string handling in Python 3 is most conveniently handled with the :class:`str` type even though the HTTP protocol is itself bytes oriented. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:17 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_update_link_to_?= =?utf8?q?pycrypto_=28closes_=2312351=29?= Message-ID: http://hg.python.org/cpython/rev/0cb49ca95109 changeset: 70824:0cb49ca95109 branch: 2.7 parent: 70809:5fbf0d010276 user: Benjamin Peterson date: Thu Jun 16 18:49:46 2011 -0500 summary: update link to pycrypto (closes #12351) files: Doc/library/crypto.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -27,5 +27,5 @@ A.M. Kuchling of further interest; the package contains modules for various encryption algorithms, most notably AES. These modules are not distributed with Python but available separately. See the URL -http://www.amk.ca/python/code/crypto.html for more information. +http://www.pycrypto.org for more information. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:18 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:18 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_update_link_to_?= =?utf8?q?pycrypto_=28closes_=2312351=29?= Message-ID: http://hg.python.org/cpython/rev/4d465cef3257 changeset: 70825:4d465cef3257 branch: 3.2 parent: 70819:8a9d25804c3d user: Benjamin Peterson date: Thu Jun 16 18:49:46 2011 -0500 summary: update link to pycrypto (closes #12351) files: Doc/library/crypto.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -25,5 +25,5 @@ A.M. Kuchling of further interest; the package contains modules for various encryption algorithms, most notably AES. These modules are not distributed with Python but available separately. See the URL -http://www.amk.ca/python/code/crypto.html for more information. +http://www.pycrypto.org for more information. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:19 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:19 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/976915e35ccd changeset: 70826:976915e35ccd parent: 70821:fd6446a88fe3 parent: 70825:4d465cef3257 user: Benjamin Peterson date: Thu Jun 16 18:50:21 2011 -0500 summary: merge 3.2 files: Doc/library/crypto.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -25,5 +25,5 @@ A.M. Kuchling of further interest; the package contains modules for various encryption algorithms, most notably AES. These modules are not distributed with Python but available separately. See the URL -http://www.amk.ca/python/code/crypto.html for more information. +http://www.pycrypto.org for more information. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:20 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:20 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/505fb7045aad changeset: 70827:505fb7045aad branch: 3.2 parent: 70825:4d465cef3257 parent: 70822:0fe3b81c7c89 user: Benjamin Peterson date: Thu Jun 16 18:51:24 2011 -0500 summary: merge heads files: Doc/whatsnew/3.2.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -385,7 +385,7 @@ ===================================================== This informational PEP clarifies how bytes/text issues are to be handled by the -WGSI protocol. The challenge is that string handling in Python 3 is most +WSGI protocol. The challenge is that string handling in Python 3 is most conveniently handled with the :class:`str` type even though the HTTP protocol is itself bytes oriented. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:20 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:20 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/f9651488f256 changeset: 70828:f9651488f256 parent: 70826:976915e35ccd parent: 70827:505fb7045aad user: Benjamin Peterson date: Thu Jun 16 18:51:37 2011 -0500 summary: merge 3.2 files: Doc/whatsnew/3.2.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -385,7 +385,7 @@ ===================================================== This informational PEP clarifies how bytes/text issues are to be handled by the -WGSI protocol. The challenge is that string handling in Python 3 is most +WSGI protocol. The challenge is that string handling in Python 3 is most conveniently handled with the :class:`str` type even though the HTTP protocol is itself bytes oriented. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 01:48:21 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 17 Jun 2011 01:48:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/8036d819b7d0 changeset: 70829:8036d819b7d0 parent: 70828:f9651488f256 parent: 70823:cf56abd14eef user: Benjamin Peterson date: Thu Jun 16 18:51:42 2011 -0500 summary: merge heads files: -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Fri Jun 17 05:06:27 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 17 Jun 2011 05:06:27 +0200 Subject: [Python-checkins] Daily reference leaks (8036d819b7d0): sum=28 Message-ID: results for 8036d819b7d0 on branch "default" -------------------------------------------- test_packaging leaked [117, 117, 117] references, sum=351 test_pydoc leaked [0, 0, -323] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogrYOliS', '-x'] From ncoghlan at gmail.com Fri Jun 17 07:20:44 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Fri, 17 Jun 2011 15:20:44 +1000 Subject: [Python-checkins] cpython (3.2): Fix typo. In-Reply-To: References: Message-ID: On Fri, Jun 17, 2011 at 7:33 AM, raymond.hettinger wrote: > http://hg.python.org/cpython/rev/0fe3b81c7c89 > changeset: ? 70822:0fe3b81c7c89 > branch: ? ? ?3.2 > parent: ? ? ?70819:8a9d25804c3d > user: ? ? ? ?Raymond Hettinger > date: ? ? ? ?Thu Jun 16 22:32:10 2011 +0100 > summary: > ?Fix typo. > > files: > ?Doc/whatsnew/3.2.rst | ?2 +- > ?1 files changed, 1 insertions(+), 1 deletions(-) > > > diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst > --- a/Doc/whatsnew/3.2.rst > +++ b/Doc/whatsnew/3.2.rst > @@ -385,7 +385,7 @@ > ?===================================================== > > ?This informational PEP clarifies how bytes/text issues are to be handled by the > -WGSI protocol. ?The challenge is that string handling in Python 3 is most > +WSGI protocol. ?The challenge is that string handling in Python 3 is most > ?conveniently handled with the :class:`str` type even though the HTTP protocol > ?is itself bytes oriented. Ah, the cognitive scientist in me *loves* diffs like this one. Even *knowing* there's a typo on the line, it's still hard to spot :) Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Fri Jun 17 12:20:50 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 12:20:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312333=3A_restore_t?= =?utf8?q?he_previous_dir_before_removing_the_current_directory?= Message-ID: http://hg.python.org/cpython/rev/276530424350 changeset: 70830:276530424350 user: Victor Stinner date: Fri Jun 17 12:20:46 2011 +0200 summary: Issue #12333: restore the previous dir before removing the current directory packaging.tests.support.TempdirManager: removing the current directory is not allowed on Windows or Solaris. Store the current directory and restore it before removing the temporary directory (which is used as the working directory during the tests). files: Lib/packaging/tests/support.py | 13 +++++-------- 1 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py --- a/Lib/packaging/tests/support.py +++ b/Lib/packaging/tests/support.py @@ -37,7 +37,7 @@ from packaging import logger from packaging.dist import Distribution from packaging.tests import unittest -from test.support import requires_zlib +from test.support import requires_zlib, unlink __all__ = ['LoggingCatcher', 'TempdirManager', 'EnvironRestorer', 'DummyCommand', 'unittest', 'create_distribution', @@ -121,20 +121,17 @@ def setUp(self): super(TempdirManager, self).setUp() + self._olddir = os.getcwd() self._basetempdir = tempfile.mkdtemp() self._files = [] def tearDown(self): - shutil.rmtree(self._basetempdir, os.name in ('nt', 'cygwin')) + os.chdir(self._olddir) + shutil.rmtree(self._basetempdir) for handle, name in self._files: handle.close() - if os.path.exists(name): - try: - os.remove(name) - except OSError as exc: - if exc.errno != errno.ENOENT: - raise + unlink(name) super(TempdirManager, self).tearDown() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 12:38:33 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 12:38:33 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMzEw?= =?utf8?q?=3A_finalize_the_old_process_after_=5Frun=5Fafter=5Fforkers=28?= =?utf8?q?=29?= Message-ID: http://hg.python.org/cpython/rev/e6e7e42efdc2 changeset: 70831:e6e7e42efdc2 branch: 3.2 parent: 70827:505fb7045aad user: Victor Stinner date: Fri Jun 17 12:31:49 2011 +0200 summary: Issue #12310: finalize the old process after _run_after_forkers() multiprocessing: Process._bootstrap() keeps a reference to the old process to delay its finalization until after _run_after_forkers() as been executed. This change should fix a crash on Mac OS X Tiger when a lock is released after a fork. Patch written by Charles-Fran?ois Nataliv and Antoine Pitrou. files: Lib/multiprocessing/process.py | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -251,9 +251,15 @@ sys.stdin = open(os.devnull) except (OSError, ValueError): pass + old_process = _current_process _current_process = self - util._finalizer_registry.clear() - util._run_after_forkers() + try: + util._finalizer_registry.clear() + util._run_after_forkers() + finally: + # delay finalization of the old process object until after + # _run_after_forkers() is executed + del old_process util.info('child process calling self.run()') try: self.run() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 12:38:34 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 12:38:34 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_Issue_=2312310=3A_finalize_the_old_process?= =?utf8?b?IGFmdGVyIF9ydW5fYWZ0ZXJfZm9ya2Vycygp?= Message-ID: http://hg.python.org/cpython/rev/a73e5c1f57d7 changeset: 70832:a73e5c1f57d7 parent: 70830:276530424350 parent: 70831:e6e7e42efdc2 user: Victor Stinner date: Fri Jun 17 12:36:26 2011 +0200 summary: (Merge 3.2) Issue #12310: finalize the old process after _run_after_forkers() multiprocessing: Process._bootstrap() keeps a reference to the old process to delay its finalization until after _run_after_forkers() as been executed. This change should fix a crash on Mac OS X Tiger when a lock is released after a fork. Patch written by Charles-Fran?ois Nataliv and Antoine Pitrou. files: Lib/multiprocessing/process.py | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -267,9 +267,15 @@ sys.stdin = open(os.devnull) except (OSError, ValueError): pass + old_process = _current_process _current_process = self - util._finalizer_registry.clear() - util._run_after_forkers() + try: + util._finalizer_registry.clear() + util._run_after_forkers() + finally: + # delay finalization of the old process object until after + # _run_after_forkers() is executed + del old_process util.info('child process calling self.run()') try: self.run() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 13:54:28 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 13:54:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312333=3A_close_fil?= =?utf8?q?es_before_removing_the_directory?= Message-ID: http://hg.python.org/cpython/rev/6e5a9f16d831 changeset: 70833:6e5a9f16d831 user: Victor Stinner date: Fri Jun 17 13:25:53 2011 +0200 summary: Issue #12333: close files before removing the directory packaging.tests.support.TempdirManager: rmtree() fails on Windows if there are still open files in the directory. files: Lib/packaging/tests/support.py | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/packaging/tests/support.py b/Lib/packaging/tests/support.py --- a/Lib/packaging/tests/support.py +++ b/Lib/packaging/tests/support.py @@ -126,13 +126,12 @@ self._files = [] def tearDown(self): - os.chdir(self._olddir) - shutil.rmtree(self._basetempdir) - for handle, name in self._files: handle.close() unlink(name) + os.chdir(self._olddir) + shutil.rmtree(self._basetempdir) super(TempdirManager, self).tearDown() def mktempfile(self): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 13:54:29 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 13:54:29 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312333=3A_run_tests?= =?utf8?q?_on_the_new_module_in_a_subprocess?= Message-ID: http://hg.python.org/cpython/rev/144cea8db9a5 changeset: 70834:144cea8db9a5 user: Victor Stinner date: Fri Jun 17 13:52:56 2011 +0200 summary: Issue #12333: run tests on the new module in a subprocess It is not possible to unload a module written in C, so use a subprocess to run the tests on the module compiled by test_build_ext(). Using a subprocess, we don't have to unload the module, save/restore sys.path, and the test can be run more than once. This commit fixes also an access error on rmtree() on Windows: because the module was not really unloaded, it was not possible to remove the temporary directory (it is not possible to remove a directory on Windows if it still contains an open file). files: Lib/packaging/tests/test_command_build_ext.py | 40 ++++------ 1 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -8,13 +8,10 @@ from packaging.errors import UnknownFileError, CompileError from packaging.command.build_ext import build_ext from packaging.compiler.extension import Extension +from test.script_helper import assert_python_ok from packaging.tests import support, unittest, verbose, unload -# http://bugs.python.org/issue4373 -# Don't load the xx module more than once. -ALREADY_TESTED = False - def _get_source_filename(): srcdir = sysconfig.get_config_var('srcdir') @@ -29,8 +26,6 @@ # Note that we're making changes to sys.path super(BuildExtTestCase, self).setUp() self.tmp_dir = self.mkdtemp() - self.sys_path = sys.path, sys.path[:] - sys.path.append(self.tmp_dir) filename = _get_source_filename() if os.path.exists(filename): shutil.copy(filename, self.tmp_dir) @@ -58,7 +53,6 @@ cmd.library_dirs = value.split(os.pathsep) def test_build_ext(self): - global ALREADY_TESTED xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') if not os.path.exists(xx_c): # skipping if we cannot find it @@ -86,29 +80,27 @@ finally: sys.stdout = old_stdout - if ALREADY_TESTED: - return - else: - ALREADY_TESTED = True + code = """if 1: + import sys + sys.path.insert(0, %r) - import xx + import xx - for attr in ('error', 'foo', 'new', 'roj'): - self.assertTrue(hasattr(xx, attr)) + for attr in ('error', 'foo', 'new', 'roj'): + assert hasattr(xx, attr) - self.assertEqual(xx.foo(2, 5), 7) - self.assertEqual(xx.foo(13, 15), 28) - self.assertEqual(xx.new().demo(), None) - doc = 'This is a template module just for instruction.' - self.assertEqual(xx.__doc__, doc) - self.assertTrue(isinstance(xx.Null(), xx.Null)) - self.assertTrue(isinstance(xx.Str(), xx.Str)) + assert xx.foo(2, 5) == 7 + assert xx.foo(13, 15) == 28 + assert xx.new().demo() is None + doc = 'This is a template module just for instruction.' + assert xx.__doc__ == doc + assert isinstance(xx.Null(), xx.Null) + assert isinstance(xx.Str(), xx.Str)""" + code = code % self.tmp_dir + assert_python_ok('-c', code) def tearDown(self): # Get everything back to normal - unload('xx') - sys.path = self.sys_path[0] - sys.path[:] = self.sys_path[1] if sys.version > "2.6": site.USER_BASE = self.old_user_base build_ext.USER_BASE = self.old_user_base -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 14:02:33 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 14:02:33 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMTMz?= =?utf8?q?=3A_fix_a_ResourceWarning_in_urllib=2Erequest?= Message-ID: http://hg.python.org/cpython/rev/ad6bdfd7dd4b changeset: 70835:ad6bdfd7dd4b branch: 3.2 parent: 70831:e6e7e42efdc2 user: Victor Stinner date: Fri Jun 17 14:01:18 2011 +0200 summary: Issue #12133: fix a ResourceWarning in urllib.request AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. files: Lib/test/test_urllib2.py | 3 +++ Lib/urllib/request.py | 2 ++ Misc/NEWS | 4 ++++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -317,6 +317,9 @@ def getresponse(self): return MockHTTPResponse(MockFile(), {}, 200, "OK") + def close(self): + pass + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1137,6 +1137,8 @@ r = h.getresponse() # an HTTPResponse instance except socket.error as err: raise URLError(err) + finally: + h.close() r.url = req.get_full_url() # This line replaces the .msg attribute of the HTTPResponse diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,10 @@ Library ------- +- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP + connection if its getresponse() method fails with a socket error. Patch + written by Ezio Melotti. + - Issue #9284: Allow inspect.findsource() to find the source of doctest functions. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 14:02:33 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 14:02:33 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_Issue_=2312133=3A_fix_a_ResourceWarning_in?= =?utf8?q?_urllib=2Erequest?= Message-ID: http://hg.python.org/cpython/rev/57a98feb508e changeset: 70836:57a98feb508e parent: 70834:144cea8db9a5 parent: 70835:ad6bdfd7dd4b user: Victor Stinner date: Fri Jun 17 14:02:18 2011 +0200 summary: (Merge 3.2) Issue #12133: fix a ResourceWarning in urllib.request AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. files: Lib/test/test_urllib2.py | 3 +++ Lib/urllib/request.py | 2 ++ Misc/NEWS | 4 ++++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -318,6 +318,9 @@ def getresponse(self): return MockHTTPResponse(MockFile(), {}, 200, "OK") + def close(self): + pass + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1146,6 +1146,8 @@ r = h.getresponse() # an HTTPResponse instance except socket.error as err: raise URLError(err) + finally: + h.close() r.url = req.get_full_url() # This line replaces the .msg attribute of the HTTPResponse diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,10 @@ Library ------- +- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP + connection if its getresponse() method fails with a socket error. Patch + written by Ezio Melotti. + - Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. Original patch by Erik Bray. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 14:06:29 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 14:06:29 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMTMz?= =?utf8?q?=3A_AbstractHTTPHandler=2Edo=5Fopen=28=29_of_urllib=2Erequest_cl?= =?utf8?q?oses_the_HTTP?= Message-ID: http://hg.python.org/cpython/rev/18e6ccc332d5 changeset: 70837:18e6ccc332d5 branch: 2.7 parent: 70824:0cb49ca95109 user: Victor Stinner date: Fri Jun 17 14:06:27 2011 +0200 summary: Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. files: Lib/test/test_urllib2.py | 5 +++++ Lib/urllib2.py | 2 ++ Misc/NEWS | 4 ++++ 3 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -293,6 +293,7 @@ self._tunnel_headers = headers else: self._tunnel_headers.clear() + def request(self, method, url, body=None, headers=None): self.method = method self.selector = url @@ -304,9 +305,13 @@ if self.raise_on_endheaders: import socket raise socket.error() + def getresponse(self): return MockHTTPResponse(MockFile(), {}, 200, "OK") + def close(self): + pass + class MockHandler: # useful for testing handler machinery # see add_ordered_mock_handlers() docstring diff --git a/Lib/urllib2.py b/Lib/urllib2.py --- a/Lib/urllib2.py +++ b/Lib/urllib2.py @@ -1172,6 +1172,8 @@ r = h.getresponse() except socket.error, err: # XXX what error? raise URLError(err) + finally: + h.close() # Pick apart the HTTPResponse object to get the addinfourl # object initialized properly. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,10 @@ Library ------- +- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP + connection if its getresponse() method fails with a socket error. Patch + written by Ezio Melotti. + - Issue #9284: Allow inspect.findsource() to find the source of doctest functions. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 14:53:39 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 14:53:39 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEwODgz?= =?utf8?q?=3A_test=5Furllib2net_closes_socket_explicitly?= Message-ID: http://hg.python.org/cpython/rev/ca18f7f35c28 changeset: 70838:ca18f7f35c28 branch: 3.2 parent: 70835:ad6bdfd7dd4b user: Victor Stinner date: Fri Jun 17 14:53:02 2011 +0200 summary: Issue #10883: test_urllib2net closes socket explicitly files: Lib/test/test_urllib2net.py | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -234,6 +234,7 @@ url = "http://www.python.org" with support.transient_internet(url, timeout=None): u = _urlopen_with_retry(url) + self.addCleanup(u.close) self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_default_timeout(self): @@ -243,6 +244,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(url) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp.raw._sock.gettimeout(), 60) @@ -254,6 +256,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(url, timeout=None) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertTrue(u.fp.raw._sock.gettimeout() is None) @@ -262,6 +265,7 @@ url = "http://www.python.org" with support.transient_internet(url): u = _urlopen_with_retry(url, timeout=120) + self.addCleanup(u.close) self.assertEqual(u.fp.raw._sock.gettimeout(), 120) FTP_HOST = "ftp://ftp.mirror.nl/pub/gnu/" @@ -270,6 +274,7 @@ self.assertTrue(socket.getdefaulttimeout() is None) with support.transient_internet(self.FTP_HOST, timeout=None): u = _urlopen_with_retry(self.FTP_HOST) + self.addCleanup(u.close) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) def test_ftp_default_timeout(self): @@ -278,6 +283,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(self.FTP_HOST) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) @@ -288,6 +294,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) @@ -295,6 +302,7 @@ def test_ftp_timeout(self): with support.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) + self.addCleanup(u.close) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 14:53:39 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 14:53:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_Issue_=2310883=3A_test=5Furllib2net_closes?= =?utf8?q?_socket_explicitly?= Message-ID: http://hg.python.org/cpython/rev/6d38060f290c changeset: 70839:6d38060f290c parent: 70836:57a98feb508e parent: 70838:ca18f7f35c28 user: Victor Stinner date: Fri Jun 17 14:53:41 2011 +0200 summary: (Merge 3.2) Issue #10883: test_urllib2net closes socket explicitly files: Lib/test/test_urllib2net.py | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -234,6 +234,7 @@ url = "http://www.python.org" with support.transient_internet(url, timeout=None): u = _urlopen_with_retry(url) + self.addCleanup(u.close) self.assertTrue(u.fp.raw._sock.gettimeout() is None) def test_http_default_timeout(self): @@ -243,6 +244,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(url) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp.raw._sock.gettimeout(), 60) @@ -254,6 +256,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(url, timeout=None) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertTrue(u.fp.raw._sock.gettimeout() is None) @@ -262,6 +265,7 @@ url = "http://www.python.org" with support.transient_internet(url): u = _urlopen_with_retry(url, timeout=120) + self.addCleanup(u.close) self.assertEqual(u.fp.raw._sock.gettimeout(), 120) FTP_HOST = "ftp://ftp.mirror.nl/pub/gnu/" @@ -270,6 +274,7 @@ self.assertTrue(socket.getdefaulttimeout() is None) with support.transient_internet(self.FTP_HOST, timeout=None): u = _urlopen_with_retry(self.FTP_HOST) + self.addCleanup(u.close) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) def test_ftp_default_timeout(self): @@ -278,6 +283,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(self.FTP_HOST) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) @@ -288,6 +294,7 @@ socket.setdefaulttimeout(60) try: u = _urlopen_with_retry(self.FTP_HOST, timeout=None) + self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) @@ -295,6 +302,7 @@ def test_ftp_timeout(self): with support.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) + self.addCleanup(u.close) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 15:18:14 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 15:18:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_posixmodule=2Ec?= =?utf8?q?=3A_fix_function_name_in_argument_parsing?= Message-ID: http://hg.python.org/cpython/rev/f6d6afe53385 changeset: 70840:f6d6afe53385 branch: 3.2 parent: 70838:ca18f7f35c28 user: Victor Stinner date: Fri Jun 17 15:15:38 2011 +0200 summary: posixmodule.c: fix function name in argument parsing Fix os.fchown() and os.open() Remove also trailing spaces and replace tabs by spaces. files: Modules/posixmodule.c | 44 +++++++++++++++--------------- 1 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -121,7 +121,7 @@ #ifdef _MSC_VER /* Microsoft compiler */ #define HAVE_GETCWD 1 #define HAVE_GETPPID 1 -#define HAVE_GETLOGIN 1 +#define HAVE_GETLOGIN 1 #define HAVE_SPAWNV 1 #define HAVE_EXECV 1 #define HAVE_PIPE 1 @@ -1133,11 +1133,11 @@ win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse) { - int code; + int code; HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const char *dot; if(!check_GetFinalPathNameByHandle()) { @@ -1233,7 +1233,7 @@ HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const wchar_t *dot; if(!check_GetFinalPathNameByHandle()) { @@ -1252,7 +1252,7 @@ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return the symlink path agin and not the actual final path. */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -1371,7 +1371,7 @@ return win32_xstat(path, result, TRUE); } -static int +static int win32_stat_w(const wchar_t* path, struct win32_stat *result) { return win32_xstat_w(path, result, TRUE); @@ -2204,7 +2204,7 @@ int fd; long uid, gid; int res; - if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -2409,7 +2409,7 @@ if (PyArg_ParseTuple(args, "|U:listdir", &po)) { WIN32_FIND_DATAW wFileData; Py_UNICODE *wnamebuf, *po_wchars; - + if (po == NULL) { /* Default arg: "." */ po_wchars = L"."; len = 1; @@ -2789,7 +2789,7 @@ int result_length; PyObject *result; wchar_t *path; - + if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) { return NULL; } @@ -2810,7 +2810,7 @@ /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ FILE_FLAG_BACKUP_SEMANTICS, NULL); - + if(hFile == INVALID_HANDLE_VALUE) { return win32_error_unicode("GetFinalPathNamyByHandle", path); return PyErr_Format(PyExc_RuntimeError, @@ -3159,7 +3159,7 @@ if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; - + /* Get WIN32_FIND_DATA structure for the path to determine if it is a symlink */ if(is_directory && @@ -4349,7 +4349,7 @@ #endif gid_t grouplist[MAX_GROUPS]; - /* On MacOSX getgroups(2) can return more than MAX_GROUPS results + /* On MacOSX getgroups(2) can return more than MAX_GROUPS results * This is a helper variable to store the intermediate result when * that happens. * @@ -4565,15 +4565,15 @@ posix_getlogin(PyObject *self, PyObject *noargs) { PyObject *result = NULL; -#ifdef MS_WINDOWS +#ifdef MS_WINDOWS wchar_t user_name[UNLEN + 1]; DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]); if (GetUserNameW(user_name, &num_chars)) { /* num_chars is the number of unicode chars plus null terminator */ result = PyUnicode_FromWideChar(user_name, num_chars - 1); - } - else + } + else result = PyErr_SetFromWindowsErr(GetLastError()); #else char *name; @@ -5257,12 +5257,12 @@ FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0); Py_END_ALLOW_THREADS - + if (reparse_point_handle==INVALID_HANDLE_VALUE) { return win32_error_unicode("readlink", path); } - + Py_BEGIN_ALLOW_THREADS /* New call DeviceIoControl to read the reparse point */ io_result = DeviceIoControl( @@ -5333,7 +5333,7 @@ int target_is_directory = 0; DWORD res; WIN32_FILE_ATTRIBUTE_DATA src_info; - + if (!check_CreateSymbolicLinkW()) { /* raise NotImplementedError */ @@ -5352,7 +5352,7 @@ Py_DECREF(src); return NULL; } - + /* if src is a directory, ensure target_is_directory==1 */ if( GetFileAttributesExW( @@ -5375,7 +5375,7 @@ { return win32_error_unicode("symlink", PyUnicode_AsUnicode(src)); } - + Py_INCREF(Py_None); return Py_None; } @@ -5573,7 +5573,7 @@ #ifdef MS_WINDOWS PyUnicodeObject *po; - if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { + if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) { Py_BEGIN_ALLOW_THREADS /* PyUnicode_AS_UNICODE OK without thread lock as it is a simple dereference. */ @@ -5588,7 +5588,7 @@ PyErr_Clear(); #endif - if (!PyArg_ParseTuple(args, "O&i|i", + if (!PyArg_ParseTuple(args, "O&i|i:open", PyUnicode_FSConverter, &ofile, &flag, &mode)) return NULL; -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 15:18:14 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 17 Jun 2011 15:18:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28Merge_3=2E2=29_posixmodule=2Ec=3A_fix_function_name_in_ar?= =?utf8?q?gument_parsing?= Message-ID: http://hg.python.org/cpython/rev/496c49ef3029 changeset: 70841:496c49ef3029 parent: 70839:6d38060f290c parent: 70840:f6d6afe53385 user: Victor Stinner date: Fri Jun 17 15:18:16 2011 +0200 summary: (Merge 3.2) posixmodule.c: fix function name in argument parsing Fix os.fchown() and os.open() Remove also trailing spaces and replace tabs by spaces. files: Modules/posixmodule.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1162,11 +1162,11 @@ win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse) { - int code; + int code; HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const char *dot; if(!check_GetFinalPathNameByHandle()) { @@ -1262,7 +1262,7 @@ HANDLE hFile, hFile2; BY_HANDLE_FILE_INFORMATION info; ULONG reparse_tag = 0; - wchar_t *target_path; + wchar_t *target_path; const wchar_t *dot; if(!check_GetFinalPathNameByHandle()) { @@ -1281,7 +1281,7 @@ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return the symlink path agin and not the actual final path. */ - FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| + FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -2275,7 +2275,7 @@ int fd; long uid, gid; int res; - if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) + if (!PyArg_ParseTuple(args, "ill:fchown", &fd, &uid, &gid)) return NULL; Py_BEGIN_ALLOW_THREADS res = fchown(fd, (uid_t) uid, (gid_t) gid); @@ -6076,7 +6076,7 @@ #ifdef MS_WINDOWS PyUnicodeObject *po; - if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { + if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) { Py_BEGIN_ALLOW_THREADS /* PyUnicode_AS_UNICODE OK without thread lock as it is a simple dereference. */ @@ -6091,7 +6091,7 @@ PyErr_Clear(); #endif - if (!PyArg_ParseTuple(args, "O&i|i", + if (!PyArg_ParseTuple(args, "O&i|i:open", PyUnicode_FSConverter, &ofile, &flag, &mode)) return NULL; @@ -8982,12 +8982,12 @@ } else { if (extract_time(PyTuple_GET_ITEM(arg, 0), - &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) { + &(buf[0].tv_sec), &(buf[0].tv_usec)) == -1) { Py_DECREF(opath); return NULL; } if (extract_time(PyTuple_GET_ITEM(arg, 1), - &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) { + &(buf[1].tv_sec), &(buf[1].tv_usec)) == -1) { Py_DECREF(opath); return NULL; } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 17:46:49 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 17 Jun 2011 17:46:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=2312313=3A_update_Makefile?= =?utf8?q?=2Epre=2Ein_to_account_for_email_tests_moving_to_=27test=27_dir?= Message-ID: http://hg.python.org/cpython/rev/c9d27c63b45c changeset: 70842:c9d27c63b45c user: R David Murray date: Fri Jun 17 11:41:49 2011 -0400 summary: #12313: update Makefile.pre.in to account for email tests moving to 'test' dir files: Makefile.pre.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -916,7 +916,7 @@ test/subprocessdata \ test/tracedmodules test/encoded_modules \ collections concurrent concurrent/futures encodings \ - email email/mime email/test email/test/data \ + email email/mime test/test_email test/test_email/data \ html json test/json_tests http dbm xmlrpc \ sqlite3 sqlite3/test \ logging csv wsgiref urllib \ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:10:30 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 17 Jun 2011 19:10:30 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExNzY3OiB1c2Ug?= =?utf8?q?context_manager_to_close_file_in_=5F=5Fgetitem=5F=5F_to_prevent_?= =?utf8?q?FD_leak?= Message-ID: http://hg.python.org/cpython/rev/fea1920ae75f changeset: 70843:fea1920ae75f branch: 3.2 parent: 70840:f6d6afe53385 user: R David Murray date: Fri Jun 17 12:54:56 2011 -0400 summary: #11767: use context manager to close file in __getitem__ to prevent FD leak All of the other methods in mailbox that create message objects take care to close the file descriptors they use, so it seems to make sense to have __getitem__ do so as well. Patch by Filip Gruszczy?ski. files: Lib/mailbox.py | 4 ++- Lib/test/test_mailbox.py | 33 +++++++++++++++++++++++++++- Misc/NEWS | 2 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -20,6 +20,7 @@ import email.message import email.generator import io +import contextlib try: if sys.platform == 'os2emx': # OS/2 EMX fcntl() not adequate @@ -76,7 +77,8 @@ if not self._factory: return self.get_message(key) else: - return self._factory(self.get_file(key)) + with contextlib.closing(self.get_file(key)) as file: + return self._factory(file) def get_message(self, key): """Return a Message representation or raise a KeyError.""" diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1201,6 +1201,37 @@ self.assertEqual(set(self._box.get_labels()), set(['blah'])) +class FakeFileLikeObject: + + def __init__(self): + self.closed = False + + def close(self): + self.closed = True + + +class FakeMailBox(mailbox.Mailbox): + + def __init__(self): + mailbox.Mailbox.__init__(self, '', lambda file: None) + self.files = [FakeFileLikeObject() for i in range(10)] + + def get_file(self, key): + return self.files[key] + + +class TestFakeMailBox(unittest.TestCase): + + def test_closing_fd(self): + box = FakeMailBox() + for i in range(10): + self.assertFalse(box.files[i].closed) + for i in range(10): + box[i] + for i in range(10): + self.assertTrue(box.files[i].closed) + + class TestMessage(TestBase): _factory = mailbox.Message # Overridden by subclasses to reuse tests @@ -2113,7 +2144,7 @@ TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage, TestMHMessage, TestBabylMessage, TestMMDFMessage, TestMessageConversion, TestProxyFile, TestPartialFile, - MaildirTestCase) + MaildirTestCase, TestFakeMailBox) support.run_unittest(*tests) support.reap_children() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,8 @@ Library ------- +- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. + - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:10:31 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 17 Jun 2011 19:10:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=2311767=3A_use_context_manager_to_close_file_in_=5F?= =?utf8?q?=5Fgetitem=5F=5F_to_prevent_FD?= Message-ID: http://hg.python.org/cpython/rev/1d7a91358517 changeset: 70844:1d7a91358517 parent: 70842:c9d27c63b45c parent: 70843:fea1920ae75f user: R David Murray date: Fri Jun 17 12:56:41 2011 -0400 summary: merge #11767: use context manager to close file in __getitem__ to prevent FD leak files: Lib/mailbox.py | 4 ++- Lib/test/test_mailbox.py | 33 +++++++++++++++++++++++++++- Misc/NEWS | 2 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -20,6 +20,7 @@ import email.message import email.generator import io +import contextlib try: if sys.platform == 'os2emx': # OS/2 EMX fcntl() not adequate @@ -76,7 +77,8 @@ if not self._factory: return self.get_message(key) else: - return self._factory(self.get_file(key)) + with contextlib.closing(self.get_file(key)) as file: + return self._factory(file) def get_message(self, key): """Return a Message representation or raise a KeyError.""" diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1201,6 +1201,37 @@ self.assertEqual(set(self._box.get_labels()), set(['blah'])) +class FakeFileLikeObject: + + def __init__(self): + self.closed = False + + def close(self): + self.closed = True + + +class FakeMailBox(mailbox.Mailbox): + + def __init__(self): + mailbox.Mailbox.__init__(self, '', lambda file: None) + self.files = [FakeFileLikeObject() for i in range(10)] + + def get_file(self, key): + return self.files[key] + + +class TestFakeMailBox(unittest.TestCase): + + def test_closing_fd(self): + box = FakeMailBox() + for i in range(10): + self.assertFalse(box.files[i].closed) + for i in range(10): + box[i] + for i in range(10): + self.assertTrue(box.files[i].closed) + + class TestMessage(TestBase): _factory = mailbox.Message # Overridden by subclasses to reuse tests @@ -2113,7 +2144,7 @@ TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage, TestMHMessage, TestBabylMessage, TestMMDFMessage, TestMessageConversion, TestProxyFile, TestPartialFile, - MaildirTestCase) + MaildirTestCase, TestFakeMailBox) support.run_unittest(*tests) support.reap_children() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,8 @@ Library ------- +- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. + - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:34 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:34 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Clean_up_packaging=2Etests?= =?utf8?q?=2Etest=5Fmixin2to3?= Message-ID: http://hg.python.org/cpython/rev/8e39e469bf22 changeset: 70845:8e39e469bf22 parent: 70821:fd6446a88fe3 user: ?ric Araujo date: Thu Jun 16 23:21:01 2011 +0200 summary: Clean up packaging.tests.test_mixin2to3 files: Lib/packaging/tests/test_mixin2to3.py | 77 ++++++++------ 1 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Lib/packaging/tests/test_mixin2to3.py b/Lib/packaging/tests/test_mixin2to3.py --- a/Lib/packaging/tests/test_mixin2to3.py +++ b/Lib/packaging/tests/test_mixin2to3.py @@ -1,5 +1,5 @@ -"""Tests for packaging.command.build_py.""" import sys +import textwrap from packaging.tests import unittest, support from packaging.compat import Mixin2to3 @@ -12,60 +12,69 @@ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_convert_code_only(self): # used to check if code gets converted properly. - code_content = "print 'test'\n" - code_handle = self.mktempfile() - code_name = code_handle.name + code = "print 'test'" - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([code_name]) - converted_code_content = "print('test')\n" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) + mixin2to3._run_2to3([fp.name]) + expected = "print('test')" - self.assertEqual(new_code_content, converted_code_content) + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_doctests_only(self): # used to check if doctests gets converted properly. - doctest_content = '"""\n>>> print test\ntest\n"""\nprint test\n\n' - doctest_handle = self.mktempfile() - doctest_name = doctest_handle.name + doctest = textwrap.dedent('''\ + """Example docstring. - doctest_handle.write(doctest_content) - doctest_handle.flush() + >>> print test + test + + It works. + """''') + + with self.mktempfile() as fp: + fp.write(doctest) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([doctest_name]) + mixin2to3._run_2to3([fp.name]) + expected = textwrap.dedent('''\ + """Example docstring. - converted_doctest_content = ['"""', '>>> print(test)', 'test', '"""', - 'print(test)', '', '', ''] - converted_doctest_content = '\n'.join(converted_doctest_content) - with open(doctest_name) as fp: - new_doctest_content = "".join(fp.readlines()) + >>> print(test) + test - self.assertEqual(new_doctest_content, converted_doctest_content) + It works. + """\n''') + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_additional_fixers(self): # used to check if use_2to3_fixers works - code_content = "type(x) is T" - code_handle = self.mktempfile() - code_name = code_handle.name + code = 'type(x) is not T' - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() + mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name], + fixers=['packaging.tests.fixer']) - mixin2to3._run_2to3(files=[code_name], doctests=[code_name], - fixers=['packaging.tests.fixer']) - converted_code_content = "isinstance(x, T)" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) - self.assertEqual(new_code_content, converted_code_content) + expected = 'not isinstance(x, T)' + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) def test_suite(): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:35 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging=3A_remove_last_me?= =?utf8?q?ntions_and_uses_of_setup=2Epy_in_the_code=2E?= Message-ID: http://hg.python.org/cpython/rev/eca2efd642fe changeset: 70846:eca2efd642fe user: ?ric Araujo date: Thu Jun 16 23:34:55 2011 +0200 summary: Packaging: remove last mentions and uses of setup.py in the code. Now only the compatibility layer (in create, util and install) talk about setup.py. files: Lib/packaging/command/build_ext.py | 5 +-- Lib/packaging/compiler/msvc9compiler.py | 8 ++-- Lib/packaging/compiler/msvccompiler.py | 3 +- Lib/packaging/compiler/unixccompiler.py | 2 +- Lib/packaging/dist.py | 9 +++-- Lib/packaging/tests/test_command_bdist_dumb.py | 16 ---------- Lib/packaging/tests/test_dist.py | 4 +- 7 files changed, 15 insertions(+), 32 deletions(-) diff --git a/Lib/packaging/command/build_ext.py b/Lib/packaging/command/build_ext.py --- a/Lib/packaging/command/build_ext.py +++ b/Lib/packaging/command/build_ext.py @@ -38,7 +38,7 @@ # XXX thoughts on how to deal with complex command-line options like # these, i.e. how to make it so fancy_getopt can suck them off the - # command line and make it look like setup.py defined the appropriate + # command line and turn them into the appropriate # lists of tuples of what-have-you. # - each command needs a callback to process its command-line options # - Command.__init__() needs access to its share of the whole @@ -287,9 +287,6 @@ def run(self): from packaging.compiler import new_compiler - # 'self.extensions', as supplied by setup.py, is a list of - # Extension instances. See the documentation for Extension (in - # distutils.extension) for details. if not self.extensions: return diff --git a/Lib/packaging/compiler/msvc9compiler.py b/Lib/packaging/compiler/msvc9compiler.py --- a/Lib/packaging/compiler/msvc9compiler.py +++ b/Lib/packaging/compiler/msvc9compiler.py @@ -130,10 +130,10 @@ raise KeyError("sdkinstallrootv2.0") except KeyError: raise PackagingPlatformError( - """Python was built with Visual Studio 2008; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2008 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") +"""Python was built with Visual Studio 2008; extensions must be built with a +compiler than can generate compatible binaries. Visual Studio 2008 was not +found on this system. If you have Cygwin installed, you can try compiling +with MingW32, by passing "-c mingw32" to pysetup.""") if version >= 9.0: self.set_macro("FrameworkVersion", self.vsbase, "clr version") diff --git a/Lib/packaging/compiler/msvccompiler.py b/Lib/packaging/compiler/msvccompiler.py --- a/Lib/packaging/compiler/msvccompiler.py +++ b/Lib/packaging/compiler/msvccompiler.py @@ -134,8 +134,7 @@ """Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2003 was not found on this system. If you have Cygwin installed, you can try -compiling with MingW32, by passing "-c mingw32" to setup.py.""") -# XXX update this comment for setup.cfg +compiling with MingW32, by passing "-c mingw32" to pysetup.""") p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: diff --git a/Lib/packaging/compiler/unixccompiler.py b/Lib/packaging/compiler/unixccompiler.py --- a/Lib/packaging/compiler/unixccompiler.py +++ b/Lib/packaging/compiler/unixccompiler.py @@ -33,7 +33,7 @@ # we need some way for outsiders to feed preprocessor/compiler/linker # flags in to us -- eg. a sysadmin might want to mandate certain flags # via a site config file, or a user might want to set something for -# compiling this module distribution only via the setup.py command +# compiling this module distribution only via the pysetup command # line, whatever. As long as these options come from something on the # current system, they can be as system-dependent as they like, and we # should just happily stuff them into the preprocessor/compiler/linker diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -47,7 +47,7 @@ # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. - # Eg. "./setup.py -n" or "./setup.py --dry-run" both take advantage of + # Eg. "pysetup -n" or "pysetup --dry-run" both take advantage of # these global options. This list should be kept to a bare minimum, # since every global option is also valid as a command option -- and we # don't want to pollute the commands with too many options that they @@ -63,14 +63,15 @@ common_usage = """\ Common commands: (see '--help-commands' for more) - setup.py build will build the package underneath 'build/' - setup.py install will install the package + pysetup run build will build the package underneath 'build/' + pysetup run install will install the package """ # options that are not propagated to the commands display_options = [ ('help-commands', None, "list all available commands"), + # XXX this is obsoleted by the pysetup metadata action ('name', None, "print package name"), ('version', 'V', @@ -360,7 +361,7 @@ return # Handle the cases of --help as a "global" option, ie. - # "setup.py --help" and "setup.py --help command ...". For the + # "pysetup run --help" and "pysetup run --help command ...". For the # former, we show global options (--dry-run, etc.) # and display-only options (--name, --version, etc.); for the # latter, we omit the display-only options and show help for diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -1,6 +1,5 @@ """Tests for distutils.command.bdist_dumb.""" -import sys import os from packaging.dist import Distribution @@ -9,15 +8,6 @@ from packaging.tests.support import requires_zlib -SETUP_PY = """\ -from distutils.run import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') -""" - - class BuildDumbTestCase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): @@ -25,12 +15,9 @@ def setUp(self): super(BuildDumbTestCase, self).setUp() self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] def tearDown(self): os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] super(BuildDumbTestCase, self).tearDown() @requires_zlib @@ -40,7 +27,6 @@ tmp_dir = self.mkdtemp() pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) self.write_file((pkg_dir, 'foo.py'), '#') self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') self.write_file((pkg_dir, 'README'), '') @@ -50,8 +36,6 @@ 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'}) os.chdir(pkg_dir) - - sys.argv[:] = ['setup.py'] cmd = bdist_dumb(dist) # so the output is the same no matter diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -4,6 +4,7 @@ import sys import logging import textwrap +import sysconfig import packaging.dist from packaging.dist import Distribution @@ -396,7 +397,8 @@ dist = Distribution() sys.argv = [] dist.help = True - dist.script_name = 'setup.py' + dist.script_name = os.path.join(sysconfig.get_path('scripts'), + 'pysetup') __, stdout = captured_stdout(dist.parse_command_line) output = [line for line in stdout.split('\n') if line.strip() != ''] -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:36 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:36 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Stop_binding_sys=2Epath_as_?= =?utf8?q?default_parameter_value_in_packaging=2E?= Message-ID: http://hg.python.org/cpython/rev/af4ad88e90b5 changeset: 70847:af4ad88e90b5 user: ?ric Araujo date: Thu Jun 16 23:43:15 2011 +0200 summary: Stop binding sys.path as default parameter value in packaging. The two public functions in database default to sys.path if the given *paths* argument is None; the private functions don?t have default values for their arguments anymore, which is fine as the public functions that call them pass their arguments down. Likewise in install, the functions will pass down their *paths* arguments down to database functions. A one-line unneeded function in install was removed instead of being changed, and the few remaining tests that used brute-force restoration of sys.path have been cleaned up to use sys.path.remove. files: Lib/packaging/database.py | 13 ++++-- Lib/packaging/install.py | 19 +++------ Lib/packaging/tests/test_command_build_ext.py | 4 +- Lib/packaging/tests/test_database.py | 11 ++--- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Lib/packaging/database.py b/Lib/packaging/database.py --- a/Lib/packaging/database.py +++ b/Lib/packaging/database.py @@ -72,7 +72,7 @@ _cache_generated_egg = False -def _yield_distributions(include_dist, include_egg, paths=sys.path): +def _yield_distributions(include_dist, include_egg, paths): """ Yield .dist-info and .egg(-info) distributions, based on the arguments @@ -92,7 +92,7 @@ yield EggInfoDistribution(dist_path) -def _generate_cache(use_egg_info=False, paths=sys.path): +def _generate_cache(use_egg_info, paths): global _cache_generated, _cache_generated_egg if _cache_generated_egg or (_cache_generated and not use_egg_info): @@ -472,7 +472,7 @@ return '-'.join([name, normalized_version]) + file_extension -def get_distributions(use_egg_info=False, paths=sys.path): +def get_distributions(use_egg_info=False, paths=None): """ Provides an iterator that looks for ``.dist-info`` directories in ``sys.path`` and returns :class:`Distribution` instances for each one of @@ -482,6 +482,9 @@ :rtype: iterator of :class:`Distribution` and :class:`EggInfoDistribution` instances """ + if paths is None: + paths = sys.path + if not _cache_enabled: for dist in _yield_distributions(True, use_egg_info, paths): yield dist @@ -513,7 +516,7 @@ :rtype: :class:`Distribution` or :class:`EggInfoDistribution` or None """ - if paths == None: + if paths is None: paths = sys.path if not _cache_enabled: @@ -632,7 +635,7 @@ def get_file_path(distribution_name, relative_path): """Return the path to a resource file.""" dist = get_distribution(distribution_name) - if dist != None: + if dist is not None: return dist.get_resource_path(relative_path) raise LookupError('no distribution named %r found' % distribution_name) diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -54,10 +54,8 @@ try: os.makedirs(os.path.dirname(new)) except OSError as e: - if e.errno == errno.EEXIST: - pass - else: - raise e + if e.errno != errno.EEXIST: + raise os.rename(old, new) yield old, new @@ -169,7 +167,7 @@ os.chdir(old_dir) -def install_dists(dists, path, paths=sys.path): +def install_dists(dists, path, paths=None): """Install all distributions provided in dists, with the given prefix. If an error occurs while installing one of the distributions, uninstall all @@ -196,13 +194,13 @@ # reverting for installed_dist in installed_dists: logger.info('Reverting %s', installed_dist) - _remove_dist(installed_dist, paths) + remove(installed_dist.name, paths) raise e return installed_dists def install_from_infos(install_path=None, install=[], remove=[], conflicts=[], - paths=sys.path): + paths=None): """Install and remove the given distributions. The function signature is made to be compatible with the one of get_infos. @@ -383,11 +381,7 @@ infos[key].extend(new_infos[key]) -def _remove_dist(dist, paths=sys.path): - remove(dist.name, paths) - - -def remove(project_name, paths=sys.path, auto_confirm=True): +def remove(project_name, paths=None, auto_confirm=True): """Removes a single project from the installation. Returns True on success @@ -539,7 +533,6 @@ def _main(**attrs): if 'script_args' not in attrs: - import sys attrs['requirements'] = sys.argv[1] get_infos(**attrs) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -29,7 +29,6 @@ # Note that we're making changes to sys.path super(BuildExtTestCase, self).setUp() self.tmp_dir = self.mkdtemp() - self.sys_path = sys.path, sys.path[:] sys.path.append(self.tmp_dir) filename = _get_source_filename() if os.path.exists(filename): @@ -107,8 +106,7 @@ def tearDown(self): # Get everything back to normal unload('xx') - sys.path = self.sys_path[0] - sys.path[:] = self.sys_path[1] + sys.path.remove(self.tmp_dir) if sys.version > "2.6": site.USER_BASE = self.old_user_base build_ext.USER_BASE = self.old_user_base diff --git a/Lib/packaging/tests/test_database.py b/Lib/packaging/tests/test_database.py --- a/Lib/packaging/tests/test_database.py +++ b/Lib/packaging/tests/test_database.py @@ -259,12 +259,11 @@ disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) - self.sys_path = sys.path[:] self.fake_dists_path = os.path.join(current_path, 'fake_dists') sys.path.insert(0, self.fake_dists_path) def tearDown(self): - sys.path[:] = self.sys_path + sys.path.remove(self.fake_dists_path) enable_cache() super(TestDatabase, self).tearDown() @@ -488,20 +487,20 @@ dists = [('choxie', '2.0.0.9'), ('grammar', '1.0a4'), ('towel-stuff', '0.1'), ('babar', '0.1')] - checkLists([], _yield_distributions(False, False)) + checkLists([], _yield_distributions(False, False, sys.path)) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(False, True) + for dist in _yield_distributions(False, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(eggs, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, False) + for dist in _yield_distributions(True, False, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, True) + for dist in _yield_distributions(True, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists + eggs, found) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:37 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Remove_unused_code_in_packa?= =?utf8?q?ging=2Epypi=2Edist?= Message-ID: http://hg.python.org/cpython/rev/3f0057d7838e changeset: 70848:3f0057d7838e user: ?ric Araujo date: Thu Jun 16 23:50:17 2011 +0200 summary: Remove unused code in packaging.pypi.dist files: Lib/packaging/pypi/dist.py | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -7,15 +7,13 @@ distribution objects contain download-related information. """ -import sys -import mimetypes import re +import hashlib import tempfile import urllib.request import urllib.parse import urllib.error import urllib.parse -import hashlib from shutil import unpack_archive from packaging.errors import IrrationalVersionError @@ -318,7 +316,6 @@ path = tempfile.mkdtemp() filename = self.download(path) - content_type = mimetypes.guess_type(filename)[0] unpack_archive(filename, path) self._unpacked_dir = path -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:37 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Minor_tweaks_in_packaging?= =?utf8?b?4oCZcyB0ZXN0X2Rpc3Qu?= Message-ID: http://hg.python.org/cpython/rev/322ba22aa3c0 changeset: 70849:322ba22aa3c0 user: ?ric Araujo date: Fri Jun 17 13:24:33 2011 +0200 summary: Minor tweaks in packaging?s test_dist. - Use different Metadata objects to write and read a PKG-INFO (METADATA) file, to make sure the tested values come from the file - No need to restore methods on an instance after monkey-patching them: the methods are still the same on the class - Harmonize dedent calls files: Lib/packaging/tests/test_dist.py | 36 ++++++++----------- 1 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -10,6 +10,7 @@ from packaging.dist import Distribution from packaging.command import set_command from packaging.command.cmd import Command +from packaging.metadata import Metadata from packaging.errors import PackagingModuleError, PackagingOptionError from packaging.tests import TESTFN, captured_stdout from packaging.tests import support, unittest @@ -203,21 +204,21 @@ config_file = os.path.join(temp_home, "config1.cfg") hooks_module = os.path.join(temp_home, pyname) - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = %(modname)s.log_pre_call post-hook.test = %(modname)s.log_post_call''' % {'modname': module_name})) - self.write_file(hooks_module, textwrap.dedent(''' - record = [] + self.write_file(hooks_module, textwrap.dedent('''\ + record = [] - def log_pre_call(cmd): - record.append('pre-%s' % cmd.get_command_name()) + def log_pre_call(cmd): + record.append('pre-%s' % cmd.get_command_name()) - def log_post_call(cmd): - record.append('post-%s' % cmd.get_command_name()) - ''')) + def log_post_call(cmd): + record.append('post-%s' % cmd.get_command_name()) + ''')) set_command('packaging.tests.test_dist.test_dist') d = create_distribution([config_file]) @@ -229,15 +230,9 @@ self.addCleanup(unload, module_name) record = __import__(module_name).record - old_run = cmd.run - old_finalize = cmd.finalize_options cmd.run = lambda: record.append('run') cmd.finalize_options = lambda: record.append('finalize') - try: - d.run_command('test_dist') - finally: - cmd.run = old_run - cmd.finalize_options = old_finalize + d.run_command('test_dist') self.assertEqual(record, ['finalize', 'pre-test_dist', @@ -248,7 +243,7 @@ temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = nonexistent.dotted.name''')) @@ -263,7 +258,7 @@ temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = packaging.tests.test_dist.__doc__''')) @@ -429,14 +424,13 @@ "requires_dist": ['foo']} dist = Distribution(attrs) - metadata = dist.metadata - - # write it then reloads it PKG_INFO = io.StringIO() - metadata.write_file(PKG_INFO) + dist.metadata.write_file(PKG_INFO) PKG_INFO.seek(0) + metadata = Metadata() metadata.read_file(PKG_INFO) + self.assertEqual(metadata['name'], "package") self.assertEqual(metadata['version'], "1.0") self.assertEqual(metadata['summary'], "xxx") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:38 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Packaging_tests=3A_don?= =?utf8?q?=E2=80=99t_let_an_internal_cache_grow_indefinitely=2E?= Message-ID: http://hg.python.org/cpython/rev/27a70dfc38cc changeset: 70850:27a70dfc38cc user: ?ric Araujo date: Fri Jun 17 15:43:18 2011 +0200 summary: Packaging tests: don?t let an internal cache grow indefinitely. Victor Stinner diagnosed on #12167 that some reference leaks came from util._path_created, a set used for caching; there are two tests that cause additions to this set, so now they clear it in tearDown, avoiding 17 refleaks. (My tests show that it?s necessary to clear the set in only one test, clearing it in both does not stop more refleaks, but there?s no harm in doing it.) files: Lib/packaging/tests/test_command_bdist_dumb.py | 2 ++ Lib/packaging/tests/test_uninstall.py | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -1,6 +1,7 @@ """Tests for distutils.command.bdist_dumb.""" import os +import packaging.util from packaging.dist import Distribution from packaging.command.bdist_dumb import bdist_dumb @@ -18,6 +19,7 @@ def tearDown(self): os.chdir(self.old_location) + packaging.util._path_created.clear() super(BuildDumbTestCase, self).tearDown() @requires_zlib diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -3,6 +3,7 @@ import sys from io import StringIO import stat +import packaging.util from packaging.database import disable_cache, enable_cache from packaging.run import main @@ -43,6 +44,7 @@ def tearDown(self): os.chdir(self.cwd) + packaging.util._path_created.clear() super(UninstallTestCase, self).tearDown() def run_setup(self, *args): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:39 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Minor_tweaks_to_packaging_t?= =?utf8?q?ests=2E?= Message-ID: http://hg.python.org/cpython/rev/e914c963ab7f changeset: 70851:e914c963ab7f user: ?ric Araujo date: Fri Jun 17 15:47:41 2011 +0200 summary: Minor tweaks to packaging tests. - Move a tearDown method right after setUp - Use assertRaises instead of reinventing it - Skip a test instead of commenting it out, as a reminder files: Lib/packaging/tests/test_command_build_ext.py | 20 ++-- Lib/packaging/tests/test_pypi_dist.py | 34 +++++----- Lib/packaging/tests/test_util.py | 8 +-- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -37,6 +37,16 @@ site.USER_BASE = self.mkdtemp() build_ext.USER_BASE = site.USER_BASE + def tearDown(self): + # Get everything back to normal + unload('xx') + sys.path.remove(self.tmp_dir) + if sys.version > "2.6": + site.USER_BASE = self.old_user_base + build_ext.USER_BASE = self.old_user_base + + super(BuildExtTestCase, self).tearDown() + def _fixup_command(self, cmd): # When Python was build with --enable-shared, -L. is not good enough # to find the libpython.so. This is because regrtest runs it @@ -103,16 +113,6 @@ self.assertTrue(isinstance(xx.Null(), xx.Null)) self.assertTrue(isinstance(xx.Str(), xx.Str)) - def tearDown(self): - # Get everything back to normal - unload('xx') - sys.path.remove(self.tmp_dir) - if sys.version > "2.6": - site.USER_BASE = self.old_user_base - build_ext.USER_BASE = self.old_user_base - - super(BuildExtTestCase, self).tearDown() - def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) cmd = build_ext(dist) diff --git a/Lib/packaging/tests/test_pypi_dist.py b/Lib/packaging/tests/test_pypi_dist.py --- a/Lib/packaging/tests/test_pypi_dist.py +++ b/Lib/packaging/tests/test_pypi_dist.py @@ -239,7 +239,6 @@ def test_prefer_final(self): # Can order the distributions using prefer_final - fb10 = ReleaseInfo("FooBar", "1.0") # final distribution fb11a = ReleaseInfo("FooBar", "1.1a1") # alpha fb12a = ReleaseInfo("FooBar", "1.2a1") # alpha @@ -252,22 +251,23 @@ dists.sort_releases(prefer_final=False) self.assertEqual(fb12b, dists[0]) -# def test_prefer_source(self): -# # Ordering support prefer_source -# fb_source = Dist("FooBar", "1.0", type="source") -# fb_binary = Dist("FooBar", "1.0", type="binary") -# fb2_binary = Dist("FooBar", "2.0", type="binary") -# dists = ReleasesList([fb_binary, fb_source]) -# -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb_source, dists[0]) -# -# dists.sort_distributions(prefer_source=False) -# self.assertEqual(fb_binary, dists[0]) -# -# dists.append(fb2_binary) -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb2_binary, dists[0]) + @unittest.skip('method not implemented yet') + def test_prefer_source(self): + # Ordering supports prefer_source + fb_source = Dist("FooBar", "1.0", type="source") + fb_binary = Dist("FooBar", "1.0", type="binary") + fb2_binary = Dist("FooBar", "2.0", type="binary") + dists = ReleasesList([fb_binary, fb_source]) + + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb_source, dists[0]) + + dists.sort_distributions(prefer_source=False) + self.assertEqual(fb_binary, dists[0]) + + dists.append(fb2_binary) + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb2_binary, dists[0]) def test_get_last(self): dists = ReleasesList('Foo') diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -700,14 +700,8 @@ '{a**a,babar}', '{bob,b**z}', ] - msg = "%r is not supposed to be a valid pattern" for pattern in invalids: - try: - iglob(pattern) - except ValueError: - continue - else: - self.fail(msg % pattern) + self.assertRaises(ValueError, iglob, pattern) class EggInfoToDistInfoTestCase(support.TempdirManager, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:40 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:40 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Brange_merge?= Message-ID: http://hg.python.org/cpython/rev/5f2195edfab6 changeset: 70852:5f2195edfab6 parent: 70842:c9d27c63b45c parent: 70851:e914c963ab7f user: ?ric Araujo date: Fri Jun 17 19:38:38 2011 +0200 summary: Brange merge files: Lib/packaging/command/build_ext.py | 5 +- Lib/packaging/compiler/msvc9compiler.py | 8 +- Lib/packaging/compiler/msvccompiler.py | 3 +- Lib/packaging/compiler/unixccompiler.py | 2 +- Lib/packaging/database.py | 13 +- Lib/packaging/dist.py | 9 +- Lib/packaging/install.py | 19 +- Lib/packaging/pypi/dist.py | 5 +- Lib/packaging/tests/test_command_bdist_dumb.py | 18 +-- Lib/packaging/tests/test_command_build_ext.py | 16 +- Lib/packaging/tests/test_database.py | 11 +- Lib/packaging/tests/test_dist.py | 40 ++-- Lib/packaging/tests/test_mixin2to3.py | 77 +++++---- Lib/packaging/tests/test_pypi_dist.py | 34 ++-- Lib/packaging/tests/test_uninstall.py | 2 + Lib/packaging/tests/test_util.py | 8 +- 16 files changed, 123 insertions(+), 147 deletions(-) diff --git a/Lib/packaging/command/build_ext.py b/Lib/packaging/command/build_ext.py --- a/Lib/packaging/command/build_ext.py +++ b/Lib/packaging/command/build_ext.py @@ -38,7 +38,7 @@ # XXX thoughts on how to deal with complex command-line options like # these, i.e. how to make it so fancy_getopt can suck them off the - # command line and make it look like setup.py defined the appropriate + # command line and turn them into the appropriate # lists of tuples of what-have-you. # - each command needs a callback to process its command-line options # - Command.__init__() needs access to its share of the whole @@ -287,9 +287,6 @@ def run(self): from packaging.compiler import new_compiler - # 'self.extensions', as supplied by setup.py, is a list of - # Extension instances. See the documentation for Extension (in - # distutils.extension) for details. if not self.extensions: return diff --git a/Lib/packaging/compiler/msvc9compiler.py b/Lib/packaging/compiler/msvc9compiler.py --- a/Lib/packaging/compiler/msvc9compiler.py +++ b/Lib/packaging/compiler/msvc9compiler.py @@ -130,10 +130,10 @@ raise KeyError("sdkinstallrootv2.0") except KeyError: raise PackagingPlatformError( - """Python was built with Visual Studio 2008; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2008 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") +"""Python was built with Visual Studio 2008; extensions must be built with a +compiler than can generate compatible binaries. Visual Studio 2008 was not +found on this system. If you have Cygwin installed, you can try compiling +with MingW32, by passing "-c mingw32" to pysetup.""") if version >= 9.0: self.set_macro("FrameworkVersion", self.vsbase, "clr version") diff --git a/Lib/packaging/compiler/msvccompiler.py b/Lib/packaging/compiler/msvccompiler.py --- a/Lib/packaging/compiler/msvccompiler.py +++ b/Lib/packaging/compiler/msvccompiler.py @@ -134,8 +134,7 @@ """Python was built with Visual Studio 2003; extensions must be built with a compiler than can generate compatible binaries. Visual Studio 2003 was not found on this system. If you have Cygwin installed, you can try -compiling with MingW32, by passing "-c mingw32" to setup.py.""") -# XXX update this comment for setup.cfg +compiling with MingW32, by passing "-c mingw32" to pysetup.""") p = r"Software\Microsoft\NET Framework Setup\Product" for base in HKEYS: diff --git a/Lib/packaging/compiler/unixccompiler.py b/Lib/packaging/compiler/unixccompiler.py --- a/Lib/packaging/compiler/unixccompiler.py +++ b/Lib/packaging/compiler/unixccompiler.py @@ -33,7 +33,7 @@ # we need some way for outsiders to feed preprocessor/compiler/linker # flags in to us -- eg. a sysadmin might want to mandate certain flags # via a site config file, or a user might want to set something for -# compiling this module distribution only via the setup.py command +# compiling this module distribution only via the pysetup command # line, whatever. As long as these options come from something on the # current system, they can be as system-dependent as they like, and we # should just happily stuff them into the preprocessor/compiler/linker diff --git a/Lib/packaging/database.py b/Lib/packaging/database.py --- a/Lib/packaging/database.py +++ b/Lib/packaging/database.py @@ -72,7 +72,7 @@ _cache_generated_egg = False -def _yield_distributions(include_dist, include_egg, paths=sys.path): +def _yield_distributions(include_dist, include_egg, paths): """ Yield .dist-info and .egg(-info) distributions, based on the arguments @@ -92,7 +92,7 @@ yield EggInfoDistribution(dist_path) -def _generate_cache(use_egg_info=False, paths=sys.path): +def _generate_cache(use_egg_info, paths): global _cache_generated, _cache_generated_egg if _cache_generated_egg or (_cache_generated and not use_egg_info): @@ -472,7 +472,7 @@ return '-'.join([name, normalized_version]) + file_extension -def get_distributions(use_egg_info=False, paths=sys.path): +def get_distributions(use_egg_info=False, paths=None): """ Provides an iterator that looks for ``.dist-info`` directories in ``sys.path`` and returns :class:`Distribution` instances for each one of @@ -482,6 +482,9 @@ :rtype: iterator of :class:`Distribution` and :class:`EggInfoDistribution` instances """ + if paths is None: + paths = sys.path + if not _cache_enabled: for dist in _yield_distributions(True, use_egg_info, paths): yield dist @@ -513,7 +516,7 @@ :rtype: :class:`Distribution` or :class:`EggInfoDistribution` or None """ - if paths == None: + if paths is None: paths = sys.path if not _cache_enabled: @@ -632,7 +635,7 @@ def get_file_path(distribution_name, relative_path): """Return the path to a resource file.""" dist = get_distribution(distribution_name) - if dist != None: + if dist is not None: return dist.get_resource_path(relative_path) raise LookupError('no distribution named %r found' % distribution_name) diff --git a/Lib/packaging/dist.py b/Lib/packaging/dist.py --- a/Lib/packaging/dist.py +++ b/Lib/packaging/dist.py @@ -47,7 +47,7 @@ # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. - # Eg. "./setup.py -n" or "./setup.py --dry-run" both take advantage of + # Eg. "pysetup -n" or "pysetup --dry-run" both take advantage of # these global options. This list should be kept to a bare minimum, # since every global option is also valid as a command option -- and we # don't want to pollute the commands with too many options that they @@ -63,14 +63,15 @@ common_usage = """\ Common commands: (see '--help-commands' for more) - setup.py build will build the package underneath 'build/' - setup.py install will install the package + pysetup run build will build the package underneath 'build/' + pysetup run install will install the package """ # options that are not propagated to the commands display_options = [ ('help-commands', None, "list all available commands"), + # XXX this is obsoleted by the pysetup metadata action ('name', None, "print package name"), ('version', 'V', @@ -360,7 +361,7 @@ return # Handle the cases of --help as a "global" option, ie. - # "setup.py --help" and "setup.py --help command ...". For the + # "pysetup run --help" and "pysetup run --help command ...". For the # former, we show global options (--dry-run, etc.) # and display-only options (--name, --version, etc.); for the # latter, we omit the display-only options and show help for diff --git a/Lib/packaging/install.py b/Lib/packaging/install.py --- a/Lib/packaging/install.py +++ b/Lib/packaging/install.py @@ -54,10 +54,8 @@ try: os.makedirs(os.path.dirname(new)) except OSError as e: - if e.errno == errno.EEXIST: - pass - else: - raise e + if e.errno != errno.EEXIST: + raise os.rename(old, new) yield old, new @@ -169,7 +167,7 @@ os.chdir(old_dir) -def install_dists(dists, path, paths=sys.path): +def install_dists(dists, path, paths=None): """Install all distributions provided in dists, with the given prefix. If an error occurs while installing one of the distributions, uninstall all @@ -196,13 +194,13 @@ # reverting for installed_dist in installed_dists: logger.info('Reverting %s', installed_dist) - _remove_dist(installed_dist, paths) + remove(installed_dist.name, paths) raise e return installed_dists def install_from_infos(install_path=None, install=[], remove=[], conflicts=[], - paths=sys.path): + paths=None): """Install and remove the given distributions. The function signature is made to be compatible with the one of get_infos. @@ -383,11 +381,7 @@ infos[key].extend(new_infos[key]) -def _remove_dist(dist, paths=sys.path): - remove(dist.name, paths) - - -def remove(project_name, paths=sys.path, auto_confirm=True): +def remove(project_name, paths=None, auto_confirm=True): """Removes a single project from the installation. Returns True on success @@ -539,7 +533,6 @@ def _main(**attrs): if 'script_args' not in attrs: - import sys attrs['requirements'] = sys.argv[1] get_infos(**attrs) diff --git a/Lib/packaging/pypi/dist.py b/Lib/packaging/pypi/dist.py --- a/Lib/packaging/pypi/dist.py +++ b/Lib/packaging/pypi/dist.py @@ -7,15 +7,13 @@ distribution objects contain download-related information. """ -import sys -import mimetypes import re +import hashlib import tempfile import urllib.request import urllib.parse import urllib.error import urllib.parse -import hashlib from shutil import unpack_archive from packaging.errors import IrrationalVersionError @@ -318,7 +316,6 @@ path = tempfile.mkdtemp() filename = self.download(path) - content_type = mimetypes.guess_type(filename)[0] unpack_archive(filename, path) self._unpacked_dir = path diff --git a/Lib/packaging/tests/test_command_bdist_dumb.py b/Lib/packaging/tests/test_command_bdist_dumb.py --- a/Lib/packaging/tests/test_command_bdist_dumb.py +++ b/Lib/packaging/tests/test_command_bdist_dumb.py @@ -1,7 +1,7 @@ """Tests for distutils.command.bdist_dumb.""" -import sys import os +import packaging.util from packaging.dist import Distribution from packaging.command.bdist_dumb import bdist_dumb @@ -9,15 +9,6 @@ from packaging.tests.support import requires_zlib -SETUP_PY = """\ -from distutils.run import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') -""" - - class BuildDumbTestCase(support.TempdirManager, support.LoggingCatcher, unittest.TestCase): @@ -25,12 +16,10 @@ def setUp(self): super(BuildDumbTestCase, self).setUp() self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] def tearDown(self): os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] + packaging.util._path_created.clear() super(BuildDumbTestCase, self).tearDown() @requires_zlib @@ -40,7 +29,6 @@ tmp_dir = self.mkdtemp() pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) self.write_file((pkg_dir, 'foo.py'), '#') self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') self.write_file((pkg_dir, 'README'), '') @@ -50,8 +38,6 @@ 'url': 'xxx', 'author': 'xxx', 'author_email': 'xxx'}) os.chdir(pkg_dir) - - sys.argv[:] = ['setup.py'] cmd = bdist_dumb(dist) # so the output is the same no matter diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -33,6 +33,14 @@ site.USER_BASE = self.mkdtemp() build_ext.USER_BASE = site.USER_BASE + def tearDown(self): + # Get everything back to normal + if sys.version > "2.6": + site.USER_BASE = self.old_user_base + build_ext.USER_BASE = self.old_user_base + + super(BuildExtTestCase, self).tearDown() + def _fixup_command(self, cmd): # When Python was build with --enable-shared, -L. is not good enough # to find the libpython.so. This is because regrtest runs it @@ -99,14 +107,6 @@ code = code % self.tmp_dir assert_python_ok('-c', code) - def tearDown(self): - # Get everything back to normal - if sys.version > "2.6": - site.USER_BASE = self.old_user_base - build_ext.USER_BASE = self.old_user_base - - super(BuildExtTestCase, self).tearDown() - def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) cmd = build_ext(dist) diff --git a/Lib/packaging/tests/test_database.py b/Lib/packaging/tests/test_database.py --- a/Lib/packaging/tests/test_database.py +++ b/Lib/packaging/tests/test_database.py @@ -259,12 +259,11 @@ disable_cache() # Setup the path environment with our fake distributions current_path = os.path.abspath(os.path.dirname(__file__)) - self.sys_path = sys.path[:] self.fake_dists_path = os.path.join(current_path, 'fake_dists') sys.path.insert(0, self.fake_dists_path) def tearDown(self): - sys.path[:] = self.sys_path + sys.path.remove(self.fake_dists_path) enable_cache() super(TestDatabase, self).tearDown() @@ -488,20 +487,20 @@ dists = [('choxie', '2.0.0.9'), ('grammar', '1.0a4'), ('towel-stuff', '0.1'), ('babar', '0.1')] - checkLists([], _yield_distributions(False, False)) + checkLists([], _yield_distributions(False, False, sys.path)) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(False, True) + for dist in _yield_distributions(False, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(eggs, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, False) + for dist in _yield_distributions(True, False, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists, found) found = [(dist.name, dist.metadata['Version']) - for dist in _yield_distributions(True, True) + for dist in _yield_distributions(True, True, sys.path) if dist.path.startswith(self.fake_dists_path)] checkLists(dists + eggs, found) diff --git a/Lib/packaging/tests/test_dist.py b/Lib/packaging/tests/test_dist.py --- a/Lib/packaging/tests/test_dist.py +++ b/Lib/packaging/tests/test_dist.py @@ -4,11 +4,13 @@ import sys import logging import textwrap +import sysconfig import packaging.dist from packaging.dist import Distribution from packaging.command import set_command from packaging.command.cmd import Command +from packaging.metadata import Metadata from packaging.errors import PackagingModuleError, PackagingOptionError from packaging.tests import TESTFN, captured_stdout from packaging.tests import support, unittest @@ -202,21 +204,21 @@ config_file = os.path.join(temp_home, "config1.cfg") hooks_module = os.path.join(temp_home, pyname) - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = %(modname)s.log_pre_call post-hook.test = %(modname)s.log_post_call''' % {'modname': module_name})) - self.write_file(hooks_module, textwrap.dedent(''' - record = [] + self.write_file(hooks_module, textwrap.dedent('''\ + record = [] - def log_pre_call(cmd): - record.append('pre-%s' % cmd.get_command_name()) + def log_pre_call(cmd): + record.append('pre-%s' % cmd.get_command_name()) - def log_post_call(cmd): - record.append('post-%s' % cmd.get_command_name()) - ''')) + def log_post_call(cmd): + record.append('post-%s' % cmd.get_command_name()) + ''')) set_command('packaging.tests.test_dist.test_dist') d = create_distribution([config_file]) @@ -228,15 +230,9 @@ self.addCleanup(unload, module_name) record = __import__(module_name).record - old_run = cmd.run - old_finalize = cmd.finalize_options cmd.run = lambda: record.append('run') cmd.finalize_options = lambda: record.append('finalize') - try: - d.run_command('test_dist') - finally: - cmd.run = old_run - cmd.finalize_options = old_finalize + d.run_command('test_dist') self.assertEqual(record, ['finalize', 'pre-test_dist', @@ -247,7 +243,7 @@ temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = nonexistent.dotted.name''')) @@ -262,7 +258,7 @@ temp_home = self.mkdtemp() config_file = os.path.join(temp_home, "config1.cfg") - self.write_file(config_file, textwrap.dedent(''' + self.write_file(config_file, textwrap.dedent('''\ [test_dist] pre-hook.test = packaging.tests.test_dist.__doc__''')) @@ -396,7 +392,8 @@ dist = Distribution() sys.argv = [] dist.help = True - dist.script_name = 'setup.py' + dist.script_name = os.path.join(sysconfig.get_path('scripts'), + 'pysetup') __, stdout = captured_stdout(dist.parse_command_line) output = [line for line in stdout.split('\n') if line.strip() != ''] @@ -427,14 +424,13 @@ "requires_dist": ['foo']} dist = Distribution(attrs) - metadata = dist.metadata - - # write it then reloads it PKG_INFO = io.StringIO() - metadata.write_file(PKG_INFO) + dist.metadata.write_file(PKG_INFO) PKG_INFO.seek(0) + metadata = Metadata() metadata.read_file(PKG_INFO) + self.assertEqual(metadata['name'], "package") self.assertEqual(metadata['version'], "1.0") self.assertEqual(metadata['summary'], "xxx") diff --git a/Lib/packaging/tests/test_mixin2to3.py b/Lib/packaging/tests/test_mixin2to3.py --- a/Lib/packaging/tests/test_mixin2to3.py +++ b/Lib/packaging/tests/test_mixin2to3.py @@ -1,5 +1,5 @@ -"""Tests for packaging.command.build_py.""" import sys +import textwrap from packaging.tests import unittest, support from packaging.compat import Mixin2to3 @@ -12,60 +12,69 @@ @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_convert_code_only(self): # used to check if code gets converted properly. - code_content = "print 'test'\n" - code_handle = self.mktempfile() - code_name = code_handle.name + code = "print 'test'" - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([code_name]) - converted_code_content = "print('test')\n" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) + mixin2to3._run_2to3([fp.name]) + expected = "print('test')" - self.assertEqual(new_code_content, converted_code_content) + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_doctests_only(self): # used to check if doctests gets converted properly. - doctest_content = '"""\n>>> print test\ntest\n"""\nprint test\n\n' - doctest_handle = self.mktempfile() - doctest_name = doctest_handle.name + doctest = textwrap.dedent('''\ + """Example docstring. - doctest_handle.write(doctest_content) - doctest_handle.flush() + >>> print test + test + + It works. + """''') + + with self.mktempfile() as fp: + fp.write(doctest) mixin2to3 = Mixin2to3() - mixin2to3._run_2to3([doctest_name]) + mixin2to3._run_2to3([fp.name]) + expected = textwrap.dedent('''\ + """Example docstring. - converted_doctest_content = ['"""', '>>> print(test)', 'test', '"""', - 'print(test)', '', '', ''] - converted_doctest_content = '\n'.join(converted_doctest_content) - with open(doctest_name) as fp: - new_doctest_content = "".join(fp.readlines()) + >>> print(test) + test - self.assertEqual(new_doctest_content, converted_doctest_content) + It works. + """\n''') + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher') def test_additional_fixers(self): # used to check if use_2to3_fixers works - code_content = "type(x) is T" - code_handle = self.mktempfile() - code_name = code_handle.name + code = 'type(x) is not T' - code_handle.write(code_content) - code_handle.flush() + with self.mktempfile() as fp: + fp.write(code) mixin2to3 = Mixin2to3() + mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name], + fixers=['packaging.tests.fixer']) - mixin2to3._run_2to3(files=[code_name], doctests=[code_name], - fixers=['packaging.tests.fixer']) - converted_code_content = "isinstance(x, T)" - with open(code_name) as fp: - new_code_content = "".join(fp.readlines()) - self.assertEqual(new_code_content, converted_code_content) + expected = 'not isinstance(x, T)' + + with open(fp.name) as fp: + converted = fp.read() + + self.assertEqual(expected, converted) def test_suite(): diff --git a/Lib/packaging/tests/test_pypi_dist.py b/Lib/packaging/tests/test_pypi_dist.py --- a/Lib/packaging/tests/test_pypi_dist.py +++ b/Lib/packaging/tests/test_pypi_dist.py @@ -239,7 +239,6 @@ def test_prefer_final(self): # Can order the distributions using prefer_final - fb10 = ReleaseInfo("FooBar", "1.0") # final distribution fb11a = ReleaseInfo("FooBar", "1.1a1") # alpha fb12a = ReleaseInfo("FooBar", "1.2a1") # alpha @@ -252,22 +251,23 @@ dists.sort_releases(prefer_final=False) self.assertEqual(fb12b, dists[0]) -# def test_prefer_source(self): -# # Ordering support prefer_source -# fb_source = Dist("FooBar", "1.0", type="source") -# fb_binary = Dist("FooBar", "1.0", type="binary") -# fb2_binary = Dist("FooBar", "2.0", type="binary") -# dists = ReleasesList([fb_binary, fb_source]) -# -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb_source, dists[0]) -# -# dists.sort_distributions(prefer_source=False) -# self.assertEqual(fb_binary, dists[0]) -# -# dists.append(fb2_binary) -# dists.sort_distributions(prefer_source=True) -# self.assertEqual(fb2_binary, dists[0]) + @unittest.skip('method not implemented yet') + def test_prefer_source(self): + # Ordering supports prefer_source + fb_source = Dist("FooBar", "1.0", type="source") + fb_binary = Dist("FooBar", "1.0", type="binary") + fb2_binary = Dist("FooBar", "2.0", type="binary") + dists = ReleasesList([fb_binary, fb_source]) + + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb_source, dists[0]) + + dists.sort_distributions(prefer_source=False) + self.assertEqual(fb_binary, dists[0]) + + dists.append(fb2_binary) + dists.sort_distributions(prefer_source=True) + self.assertEqual(fb2_binary, dists[0]) def test_get_last(self): dists = ReleasesList('Foo') diff --git a/Lib/packaging/tests/test_uninstall.py b/Lib/packaging/tests/test_uninstall.py --- a/Lib/packaging/tests/test_uninstall.py +++ b/Lib/packaging/tests/test_uninstall.py @@ -3,6 +3,7 @@ import sys from io import StringIO import stat +import packaging.util from packaging.database import disable_cache, enable_cache from packaging.run import main @@ -43,6 +44,7 @@ def tearDown(self): os.chdir(self.cwd) + packaging.util._path_created.clear() super(UninstallTestCase, self).tearDown() def run_setup(self, *args): diff --git a/Lib/packaging/tests/test_util.py b/Lib/packaging/tests/test_util.py --- a/Lib/packaging/tests/test_util.py +++ b/Lib/packaging/tests/test_util.py @@ -700,14 +700,8 @@ '{a**a,babar}', '{bob,b**z}', ] - msg = "%r is not supposed to be a valid pattern" for pattern in invalids: - try: - iglob(pattern) - except ValueError: - continue - else: - self.fail(msg % pattern) + self.assertRaises(ValueError, iglob, pattern) class EggInfoToDistInfoTestCase(support.TempdirManager, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 19:41:41 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 19:41:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Brange_merge?= Message-ID: http://hg.python.org/cpython/rev/37158ab0402c changeset: 70853:37158ab0402c parent: 70852:5f2195edfab6 parent: 70844:1d7a91358517 user: ?ric Araujo date: Fri Jun 17 19:39:18 2011 +0200 summary: Brange merge files: Lib/mailbox.py | 4 ++- Lib/test/test_mailbox.py | 33 +++++++++++++++++++++++++++- Misc/NEWS | 2 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -20,6 +20,7 @@ import email.message import email.generator import io +import contextlib try: if sys.platform == 'os2emx': # OS/2 EMX fcntl() not adequate @@ -76,7 +77,8 @@ if not self._factory: return self.get_message(key) else: - return self._factory(self.get_file(key)) + with contextlib.closing(self.get_file(key)) as file: + return self._factory(file) def get_message(self, key): """Return a Message representation or raise a KeyError.""" diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -1201,6 +1201,37 @@ self.assertEqual(set(self._box.get_labels()), set(['blah'])) +class FakeFileLikeObject: + + def __init__(self): + self.closed = False + + def close(self): + self.closed = True + + +class FakeMailBox(mailbox.Mailbox): + + def __init__(self): + mailbox.Mailbox.__init__(self, '', lambda file: None) + self.files = [FakeFileLikeObject() for i in range(10)] + + def get_file(self, key): + return self.files[key] + + +class TestFakeMailBox(unittest.TestCase): + + def test_closing_fd(self): + box = FakeMailBox() + for i in range(10): + self.assertFalse(box.files[i].closed) + for i in range(10): + box[i] + for i in range(10): + self.assertTrue(box.files[i].closed) + + class TestMessage(TestBase): _factory = mailbox.Message # Overridden by subclasses to reuse tests @@ -2113,7 +2144,7 @@ TestBabyl, TestMessage, TestMaildirMessage, TestMboxMessage, TestMHMessage, TestBabylMessage, TestMMDFMessage, TestMessageConversion, TestProxyFile, TestPartialFile, - MaildirTestCase) + MaildirTestCase, TestFakeMailBox) support.run_unittest(*tests) support.reap_children() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,8 @@ Library ------- +- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. + - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 17 21:10:33 2011 From: python-checkins at python.org (eric.araujo) Date: Fri, 17 Jun 2011 21:10:33 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Make_decorators_used_in_pac?= =?utf8?q?kaging_preserve_docstrings?= Message-ID: http://hg.python.org/cpython/rev/203407036e46 changeset: 70854:203407036e46 user: ?ric Araujo date: Fri Jun 17 21:10:21 2011 +0200 summary: Make decorators used in packaging preserve docstrings files: Lib/packaging/pypi/simple.py | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -15,8 +15,8 @@ import urllib.error import os - from fnmatch import translate +from functools import wraps from packaging import logger from packaging.metadata import Metadata from packaging.version import get_version_predicate @@ -53,8 +53,9 @@ def socket_timeout(timeout=SOCKET_TIMEOUT): """Decorator to add a socket timeout when requesting pages on PyPI. """ - def _socket_timeout(func): - def _socket_timeout(self, *args, **kwargs): + def wrapper(func): + @wraps(func) + def wrapped(self, *args, **kwargs): old_timeout = socket.getdefaulttimeout() if hasattr(self, "_timeout"): timeout = self._timeout @@ -63,13 +64,14 @@ return func(self, *args, **kwargs) finally: socket.setdefaulttimeout(old_timeout) - return _socket_timeout - return _socket_timeout + return wrapped + return wrapper def with_mirror_support(): """Decorator that makes the mirroring support easier""" def wrapper(func): + @wraps(func) def wrapped(self, *args, **kwargs): try: return func(self, *args, **kwargs) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 02:51:31 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 18 Jun 2011 02:51:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_edit_and_rewrite?= Message-ID: http://hg.python.org/cpython/rev/f041d2223ed3 changeset: 70855:f041d2223ed3 user: Benjamin Peterson date: Fri Jun 17 19:54:52 2011 -0500 summary: edit and rewrite files: Doc/library/faulthandler.rst | 75 ++++++++++++----------- 1 files changed, 40 insertions(+), 35 deletions(-) diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -4,31 +4,36 @@ .. module:: faulthandler :synopsis: Dump the Python traceback. -This module contains functions to dump the Python traceback explicitly, on a -fault, after a timeout or on a user signal. Call :func:`faulthandler.enable` to -install fault handlers for :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, -:const:`SIGBUS` and :const:`SIGILL` signals. You can also enable them at -startup by setting the :envvar:`PYTHONFAULTHANDLER` environment variable or by -using :option:`-X` ``faulthandler`` command line option. +This module contains functions to dump Python tracebacks explicitly, on a fault, +after a timeout, or on a user signal. Call :func:`faulthandler.enable` to +install fault handlers for the :const:`SIGSEGV`, :const:`SIGFPE`, +:const:`SIGABRT`, :const:`SIGBUS`, and :const:`SIGILL` signals. You can also +enable them at startup by setting the :envvar:`PYTHONFAULTHANDLER` environment +variable or by using :option:`-X` ``faulthandler`` command line option. -The fault handler is compatible with system fault handlers like Apport or -the Windows fault handler. The module uses an alternative stack for signal -handlers, if the :c:func:`sigaltstack` function is available, to be able to -dump the traceback even on a stack overflow. +The fault handler is compatible with system fault handlers like Apport or the +Windows fault handler. The module uses an alternative stack for signal handlers +if the :c:func:`sigaltstack` function is available. This allows it to dump the +traceback even on a stack overflow. -The fault handler is called on catastrophic cases and so can only use -signal-safe functions (e.g. it cannot allocate memory on the heap). That's why -the traceback is limited: only support ASCII encoding (use the -``backslashreplace`` error handler), limit each string to 100 characters, don't -print the source code (only the filename, the function name and the line -number), limit to 100 frames and 100 threads. +The fault handler is called on catastrophic cases and therefore can only use +signal-safe functions (e.g. it cannot allocate memory on the heap). Because of +this limitation traceback dumping is minimal compared to normal Python +tracebacks: -By default, the Python traceback is written to :data:`sys.stderr`. Start your -graphical applications in a terminal and run your server in foreground to see -the traceback, or specify a log file to :func:`faulthandler.enable()`. +* Only ASCII is supported. The ``backslashreplace`` error handler is used on + encoding. +* Each string is limited to 100 characters. +* Only the the filename, the function name and the line number are + displayed. (no source code) +* It is limited to 100 frames and 100 threads. -The module is implemented in C to be able to dump a traceback on a crash or -when Python is blocked (e.g. deadlock). +By default, the Python traceback is written to :data:`sys.stderr`. To see +tracebacks, applications must be run in the terminal. A log file can +alternatively be passed to :func:`faulthandler.enable`. + +The module is implemented in C, so tracebacks can be dumped on a crash or when +Python is deadlocked. .. versionadded:: 3.3 @@ -38,8 +43,9 @@ .. function:: dump_traceback(file=sys.stderr, all_threads=True) - Dump the traceback of all threads, or of the current thread if *all_threads* - is ``False``, into *file*. + Dump the traceback of all threads into *file*. If *all_threads* is ``True``, + produce tracebacks for every running thread. Otherwise, dump only the current + thread. Fault handler state @@ -47,11 +53,11 @@ .. function:: enable(file=sys.stderr, all_threads=True) - Enable the fault handler: install handlers for :const:`SIGSEGV`, + Enable the fault handler: install handlers for the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and :const:`SIGILL` - signals to dump the Python traceback. It dumps the traceback of the all - threads, or of the current thread if *all_threads* is ``False``, into - *file*. + signals to dump the Python traceback. If *all_threads* is ``True``, + produce tracebacks for every running thread. Otherwise, dump only the current + thread. .. function:: disable() @@ -69,15 +75,14 @@ .. function:: dump_tracebacks_later(timeout, repeat=False, file=sys.stderr, exit=False) Dump the tracebacks of all threads, after a timeout of *timeout* seconds, or - each *timeout* seconds if *repeat* is ``True``. If *exit* is True, call - :c:func:`_exit` with status=1 after dumping the tracebacks to terminate - immediatly the process, which is not safe. For example, :c:func:`_exit` - doesn't flush file buffers. If the function is called twice, the new call - replaces previous parameters (resets the timeout). The timer has a - sub-second resolution. + every *timeout* seconds if *repeat* is ``True``. If *exit* is ``True``, call + :c:func:`_exit` with status=1 after dumping the tracebacks. (Note + :c:func:`_exit` doesn't flush file buffers.) If the function is called twice, + the new call replaces previous parameters and resets the timeout. The timer + has a sub-second resolution. - This function is implemented using a watchdog thread, and therefore is - not available if Python is compiled with threads disabled. + This function is implemented using a watchdog thread and therefore is not + available if Python is compiled with threads disabled. .. function:: cancel_dump_tracebacks_later() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 03:16:07 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 18 Jun 2011 03:16:07 +0200 (CEST) Subject: [Python-checkins] r88854 - tracker/instances/python-dev/extensions/local_replace.py Message-ID: <3Qx0rl2wfmzM0N@mail.python.org> Author: ezio.melotti Date: Sat Jun 18 03:16:07 2011 New Revision: 88854 Log: Linkify hg changesets id before svn revisions. Modified: tracker/instances/python-dev/extensions/local_replace.py Modified: tracker/instances/python-dev/extensions/local_replace.py ============================================================================== --- tracker/instances/python-dev/extensions/local_replace.py (original) +++ tracker/instances/python-dev/extensions/local_replace.py Sat Jun 18 03:16:07 2011 @@ -73,16 +73,16 @@ # these regexs have test in tests/test_local_replace.py substitutions = [ - # r12345, r 12345, rev12345, rev 12345, revision12345, revision 12345 - (re.compile(r'\b(?r(ev(ision)?)?\s*)(?P\d+)'), - r'\g\g'), - # deadbeeffeed (hashes with exactly twelve or forty chars) (re.compile(r'\b(?[a-fA-F0-9]{40})\b'), r'\g'), (re.compile(r'\b(?[a-fA-F0-9]{12})\b'), r'\g'), + # r12345, r 12345, rev12345, rev 12345, revision12345, revision 12345 + (re.compile(r'\b(?r(ev(ision)?)?\s*)(?P\d+)'), + r'\g\g'), + # Lib/somefile.py, Lib/somefile.py:123, Modules/somemodule.c:123, ... (re.compile(r'(?P(?(?:Demo|Doc|Grammar|' r'Include|Lib|Mac|Misc|Modules|Parser|PC|PCbuild|Python|' From python-checkins at python.org Sat Jun 18 04:26:07 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 04:26:07 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzExNzAwOiBwcm94?= =?utf8?q?y_object_close_methods_can_now_be_called_multiple_times?= Message-ID: http://hg.python.org/cpython/rev/b89d193cbca5 changeset: 70856:b89d193cbca5 branch: 2.7 parent: 70837:18e6ccc332d5 user: R David Murray date: Fri Jun 17 22:23:04 2011 -0400 summary: #11700: proxy object close methods can now be called multiple times This makes them work like the close provided by regular file objects. This patch also backports the close-the-underlying-file code for _ProxyFile objects that was introduced along with context manager support in the 3.x branch. files: Lib/mailbox.py | 11 ++++++++++- Lib/test/test_mailbox.py | 10 +++++++++- Misc/NEWS | 3 +++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1854,7 +1854,10 @@ def close(self): """Close the file.""" - del self._file + if hasattr(self, '_file'): + if hasattr(self._file, 'close'): + self._file.close() + del self._file def _read(self, size, read_method): """Read size bytes using read_method.""" @@ -1898,6 +1901,12 @@ size = remaining return _ProxyFile._read(self, size, read_method) + def close(self): + # do *not* close the underlying file object for partial files, + # since it's global to the mailbox object + if hasattr(self, '_file'): + del self._file + def _lock_file(f, dotlock=True): """Lock file f using lockf and dot locking.""" diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -174,6 +174,13 @@ self.assertEqual(self._box.get_file(key1).read().replace(os.linesep, '\n'), _sample_message) + def test_get_file_can_be_closed_twice(self): + # Issue 11700 + key = self._box.add(_sample_message) + f = self._box.get_file(key) + f.close() + f.close() + def test_iterkeys(self): # Get keys using iterkeys() self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False) @@ -1670,7 +1677,8 @@ def _test_close(self, proxy): # Close a file proxy.close() - self.assertRaises(AttributeError, lambda: proxy.close()) + # Issue 11700 subsequent closes should be a no-op, not an error. + proxy.close() class TestProxyFile(TestProxyFileBase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Library ------- +- Issue #11700: mailbox proxy object close methods can now be called multiple + times without error, and _ProxyFile now closes the wrapped file. + - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP connection if its getresponse() method fails with a socket error. Patch written by Ezio Melotti. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 04:26:08 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 04:26:08 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExNzAwOiBwcm94?= =?utf8?q?y_object_close_methods_can_now_be_called_multiple_times?= Message-ID: http://hg.python.org/cpython/rev/8319db2dd342 changeset: 70857:8319db2dd342 branch: 3.2 parent: 70843:fea1920ae75f user: R David Murray date: Fri Jun 17 22:24:05 2011 -0400 summary: #11700: proxy object close methods can now be called multiple times This makes them work like the close provided by regular file objects. files: Lib/mailbox.py | 14 ++++++++++---- Lib/test/test_mailbox.py | 13 ++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1923,9 +1923,10 @@ def close(self): """Close the file.""" - if hasattr(self._file, 'close'): - self._file.close() - del self._file + if hasattr(self, '_file'): + if hasattr(self._file, 'close'): + self._file.close() + del self._file def _read(self, size, read_method): """Read size bytes using read_method.""" @@ -1957,6 +1958,10 @@ @property def closed(self): + if not hasattr(self, '_file'): + return True + if not hasattr(self._file, 'closed'): + return False return self._file.closed @@ -1995,7 +2000,8 @@ def close(self): # do *not* close the underlying file object for partial files, # since it's global to the mailbox object - del self._file + if hasattr(self, '_file'): + del self._file def _lock_file(f, dotlock=True): diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -297,6 +297,13 @@ self.assertEqual(data1.decode('ascii').replace(os.linesep, '\n'), _sample_message) + def test_get_file_can_be_closed_twice(self): + # Issue 11700 + key = self._box.add(_sample_message) + f = self._box.get_file(key) + f.close() + f.close() + def test_iterkeys(self): # Get keys using iterkeys() self._check_iteration(self._box.keys, do_keys=True, do_values=False) @@ -1862,8 +1869,12 @@ def _test_close(self, proxy): # Close a file + self.assertFalse(proxy.closed) proxy.close() - self.assertRaises(AttributeError, lambda: proxy.close()) + self.assertTrue(proxy.closed) + # Issue 11700 subsequent closes should be a no-op. + proxy.close() + self.assertTrue(proxy.closed) class TestProxyFile(TestProxyFileBase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #11700: mailbox proxy object close methods can now be called multiple + times without error. + - Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 04:26:09 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 04:26:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=2311700=3A_proxy_object_close_methods_can_now_be_call?= =?utf8?q?ed_multiple_times?= Message-ID: http://hg.python.org/cpython/rev/0705b9037b20 changeset: 70858:0705b9037b20 parent: 70855:f041d2223ed3 parent: 70857:8319db2dd342 user: R David Murray date: Fri Jun 17 22:25:14 2011 -0400 summary: merge #11700: proxy object close methods can now be called multiple times files: Lib/mailbox.py | 14 ++++++++++---- Lib/test/test_mailbox.py | 13 ++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1923,9 +1923,10 @@ def close(self): """Close the file.""" - if hasattr(self._file, 'close'): - self._file.close() - del self._file + if hasattr(self, '_file'): + if hasattr(self._file, 'close'): + self._file.close() + del self._file def _read(self, size, read_method): """Read size bytes using read_method.""" @@ -1957,6 +1958,10 @@ @property def closed(self): + if not hasattr(self, '_file'): + return True + if not hasattr(self._file, 'closed'): + return False return self._file.closed @@ -1995,7 +2000,8 @@ def close(self): # do *not* close the underlying file object for partial files, # since it's global to the mailbox object - del self._file + if hasattr(self, '_file'): + del self._file def _lock_file(f, dotlock=True): diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -297,6 +297,13 @@ self.assertEqual(data1.decode('ascii').replace(os.linesep, '\n'), _sample_message) + def test_get_file_can_be_closed_twice(self): + # Issue 11700 + key = self._box.add(_sample_message) + f = self._box.get_file(key) + f.close() + f.close() + def test_iterkeys(self): # Get keys using iterkeys() self._check_iteration(self._box.keys, do_keys=True, do_values=False) @@ -1862,8 +1869,12 @@ def _test_close(self, proxy): # Close a file + self.assertFalse(proxy.closed) proxy.close() - self.assertRaises(AttributeError, lambda: proxy.close()) + self.assertTrue(proxy.closed) + # Issue 11700 subsequent closes should be a no-op. + proxy.close() + self.assertTrue(proxy.closed) class TestProxyFile(TestProxyFileBase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,9 @@ Library ------- +- Issue #11700: mailbox proxy object close methods can now be called multiple + times without error. + - Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Sat Jun 18 05:12:06 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 18 Jun 2011 05:12:06 +0200 Subject: [Python-checkins] Daily reference leaks (f041d2223ed3): sum=300 Message-ID: results for f041d2223ed3 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pydoc leaked [0, 323, -323] references, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogIQzBU2', '-x'] From python-checkins at python.org Sat Jun 18 17:46:17 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 17:46:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=2311781=3A_update_windows_?= =?utf8?q?build_script_to_account_for_move_of_email_tests?= Message-ID: http://hg.python.org/cpython/rev/a6c5da661428 changeset: 70859:a6c5da661428 user: R David Murray date: Sat Jun 18 11:45:59 2011 -0400 summary: #11781: update windows build script to account for move of email tests files: Tools/msi/msi.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1057,14 +1057,14 @@ lib.add_file("turtle.cfg") if dir=="pydoc_data": lib.add_file("_pydoc.css") - if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email": + if dir=="data" and parent.physical=="test_email": # This should contain all non-.svn files listed in subversion for f in os.listdir(lib.absolute): if f.endswith(".txt") or f==".svn":continue if f.endswith(".au") or f.endswith(".gif"): lib.add_file(f) else: - print("WARNING: New file %s in email/test/data" % f) + print("WARNING: New file %s in test/test_email/data" % f) for f in os.listdir(lib.absolute): if os.path.isdir(os.path.join(lib.absolute, f)): pydirs.append((lib, f)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 18:34:16 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 18:34:16 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExNTg0OiBtYWtl?= =?utf8?q?_decode=5Fheader_handle_Header_objects_correctly?= Message-ID: http://hg.python.org/cpython/rev/d62e5682a8ac changeset: 70860:d62e5682a8ac branch: 3.2 parent: 70857:8319db2dd342 user: R David Murray date: Sat Jun 18 12:30:55 2011 -0400 summary: #11584: make decode_header handle Header objects correctly This updates b21fdfa0019c, which fixed this bug incorrectly. files: Lib/email/header.py | 5 +++-- Lib/email/test/test_email.py | 4 ++-- Misc/NEWS | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/email/header.py b/Lib/email/header.py --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -73,9 +73,10 @@ An email.errors.HeaderParseError may be raised when certain decoding error occurs (e.g. a base64 decoding exception). """ - # If it is a Header object, we can just return the chunks. + # If it is a Header object, we can just return the encoded chunks. if hasattr(header, '_chunks'): - return list(header._chunks) + return [(_charset._encode(string, str(charset)), str(charset)) + for string, charset in header._chunks] # If no encoding, just return the header with no charset. if not ecre.search(header): return [(header, None)] diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -4176,8 +4176,8 @@ def test_escaped_8bit_header(self): x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' - x = x.decode('ascii', 'surrogateescape') - h = Header(x, charset=email.charset.UNKNOWN8BIT) + e = x.decode('ascii', 'surrogateescape') + h = Header(e, charset=email.charset.UNKNOWN8BIT) self.assertEqual(str(h), 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #11584: email.header.decode_header no longer fails if the header + passed to it is a Header object. + - Issue #11700: mailbox proxy object close methods can now be called multiple times without error. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 18:34:17 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 18:34:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=2311584=3A_make_decode=5Fheader_handle_Header_objects?= =?utf8?q?_correctly?= Message-ID: http://hg.python.org/cpython/rev/ce033d252a6d changeset: 70861:ce033d252a6d parent: 70859:a6c5da661428 parent: 70860:d62e5682a8ac user: R David Murray date: Sat Jun 18 12:32:27 2011 -0400 summary: merge #11584: make decode_header handle Header objects correctly This updates 12e39cd7a0e4 (merge of b21fdfa0019c), which fixed this bug incorrectly. files: Lib/email/header.py | 5 +++-- Lib/test/test_email/test_email.py | 4 ++-- Misc/NEWS | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Lib/email/header.py b/Lib/email/header.py --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -73,9 +73,10 @@ An email.errors.HeaderParseError may be raised when certain decoding error occurs (e.g. a base64 decoding exception). """ - # If it is a Header object, we can just return the chunks. + # If it is a Header object, we can just return the encoded chunks. if hasattr(header, '_chunks'): - return list(header._chunks) + return [(_charset._encode(string, str(charset)), str(charset)) + for string, charset in header._chunks] # If no encoding, just return the header with no charset. if not ecre.search(header): return [(header, None)] diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -4324,8 +4324,8 @@ def test_escaped_8bit_header(self): x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' - x = x.decode('ascii', 'surrogateescape') - h = Header(x, charset=email.charset.UNKNOWN8BIT) + e = x.decode('ascii', 'surrogateescape') + h = Header(e, charset=email.charset.UNKNOWN8BIT) self.assertEqual(str(h), 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,9 @@ Library ------- +- Issue #11584: email.header.decode_header no longer fails if the header + passed to it is a Header object. + - Issue #11700: mailbox proxy object close methods can now be called multiple times without error. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 19:02:59 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 19:02:59 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExNTg0OiBtYWtl?= =?utf8?q?_Header_and_make=5Fheader_handle_binary_unknown-8bit_input?= Message-ID: http://hg.python.org/cpython/rev/3875ccea6367 changeset: 70862:3875ccea6367 branch: 3.2 parent: 70860:d62e5682a8ac user: R David Murray date: Sat Jun 18 12:57:28 2011 -0400 summary: #11584: make Header and make_header handle binary unknown-8bit input Analogous to the decode_header fix, this fix makes Header.append and make_header correctly handle the unknown-8bit charset introduced by email5.1, when the input to them is binary strings. Previous to this fix the make_header(decode_header(x)) == x invariant was broken in the face of the unknown-8bit charset. files: Lib/email/header.py | 5 ++++- Lib/email/test/test_email.py | 15 +++++++++++++++ Misc/NEWS | 3 ++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Lib/email/header.py b/Lib/email/header.py --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -275,7 +275,10 @@ charset = Charset(charset) if not isinstance(s, str): input_charset = charset.input_codec or 'us-ascii' - s = s.decode(input_charset, errors) + if input_charset == _charset.UNKNOWN8BIT: + s = s.decode('us-ascii', 'surrogateescape') + else: + s = s.decode(input_charset, errors) # Ensure that the bytes we're storing can be decoded to the output # character set, otherwise an early error is thrown. output_charset = charset.output_codec or 'us-ascii' diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -4182,6 +4182,21 @@ 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + def test_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + h = Header(x, charset=email.charset.UNKNOWN8BIT) + self.assertEqual(str(h), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + + def test_make_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + h = Header(x, charset=email.charset.UNKNOWN8BIT) + h2 = email.header.make_header(email.header.decode_header(h)) + self.assertEqual(str(h2), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h2), [(x, 'unknown-8bit')]) + def test_modify_returned_list_does_not_change_header(self): h = Header('test') chunks = email.header.decode_header(h) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -26,7 +26,8 @@ ------- - Issue #11584: email.header.decode_header no longer fails if the header - passed to it is a Header object. + passed to it is a Header object, and Header/make_header no longer fail + if given binary unknown-8bit input. - Issue #11700: mailbox proxy object close methods can now be called multiple times without error. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 18 19:03:00 2011 From: python-checkins at python.org (r.david.murray) Date: Sat, 18 Jun 2011 19:03:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=2311584=3A_make_Header_and_make=5Fheader_handle_binar?= =?utf8?q?y_unknown-8bit_input?= Message-ID: http://hg.python.org/cpython/rev/9569d8c4c781 changeset: 70863:9569d8c4c781 parent: 70861:ce033d252a6d parent: 70862:3875ccea6367 user: R David Murray date: Sat Jun 18 13:02:42 2011 -0400 summary: merge #11584: make Header and make_header handle binary unknown-8bit input files: Lib/email/header.py | 5 ++++- Lib/test/test_email/test_email.py | 15 +++++++++++++++ Misc/NEWS | 3 ++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Lib/email/header.py b/Lib/email/header.py --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -275,7 +275,10 @@ charset = Charset(charset) if not isinstance(s, str): input_charset = charset.input_codec or 'us-ascii' - s = s.decode(input_charset, errors) + if input_charset == _charset.UNKNOWN8BIT: + s = s.decode('us-ascii', 'surrogateescape') + else: + s = s.decode(input_charset, errors) # Ensure that the bytes we're storing can be decoded to the output # character set, otherwise an early error is thrown. output_charset = charset.output_codec or 'us-ascii' diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -4330,6 +4330,21 @@ 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + def test_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + h = Header(x, charset=email.charset.UNKNOWN8BIT) + self.assertEqual(str(h), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + + def test_make_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + h = Header(x, charset=email.charset.UNKNOWN8BIT) + h2 = email.header.make_header(email.header.decode_header(h)) + self.assertEqual(str(h2), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h2), [(x, 'unknown-8bit')]) + def test_modify_returned_list_does_not_change_header(self): h = Header('test') chunks = email.header.decode_header(h) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -194,7 +194,8 @@ ------- - Issue #11584: email.header.decode_header no longer fails if the header - passed to it is a Header object. + passed to it is a Header object, and Header/make_header no longer fail + if given binary unknown-8bit input. - Issue #11700: mailbox proxy object close methods can now be called multiple times without error. -- Repository URL: http://hg.python.org/cpython From tjreedy at udel.edu Sat Jun 18 22:17:51 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Sat, 18 Jun 2011 16:17:51 -0400 Subject: [Python-checkins] cpython: #11781: update windows build script to account for move of email tests In-Reply-To: References: Message-ID: <4DFD07EF.6060405@udel.edu> On 6/18/2011 11:46 AM, r.david.murray wrote: > http://hg.python.org/cpython/rev/a6c5da661428 > changeset: 70859:a6c5da661428 > user: R David Murray > date: Sat Jun 18 11:45:59 2011 -0400 > summary: > #11781: update windows build script to account for move of email tests > > files: > Tools/msi/msi.py | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > > diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py > --- a/Tools/msi/msi.py > +++ b/Tools/msi/msi.py > @@ -1057,14 +1057,14 @@ > lib.add_file("turtle.cfg") > if dir=="pydoc_data": > lib.add_file("_pydoc.css") > - if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email": > + if dir=="data" and parent.physical=="test_email": > # This should contain all non-.svn files listed in subversion Should this be mercurial > for f in os.listdir(lib.absolute): > if f.endswith(".txt") or f==".svn":continue and this .hg? From python-checkins at python.org Sun Jun 19 01:42:45 2011 From: python-checkins at python.org (r.david.murray) Date: Sun, 19 Jun 2011 01:42:45 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzY3NzE6IGZpeCBk?= =?utf8?q?ocs=3A_curses=2Ewrapper_is_exposed_as_a_function=2C_not_a_module?= Message-ID: http://hg.python.org/cpython/rev/dc78ab3f7bc5 changeset: 70864:dc78ab3f7bc5 branch: 2.7 parent: 70856:b89d193cbca5 user: R David Murray date: Sat Jun 18 19:31:22 2011 -0400 summary: #6771: fix docs: curses.wrapper is exposed as a function, not a module Patch by July Tikhonov. files: Doc/library/curses.rst | 47 ++++++++--------------------- 1 files changed, 13 insertions(+), 34 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -44,10 +44,6 @@ Module :mod:`curses.textpad` Editable text widget for curses supporting :program:`Emacs`\ -like bindings. - Module :mod:`curses.wrapper` - Convenience function to ensure proper terminal setup and resetting on - application entry and exit. - :ref:`curses-howto` Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. @@ -595,6 +591,19 @@ foreground color on the default background. +.. function:: wrapper(func, ...) + + Initialize curses and call another callable object, *func*, which should be the + rest of your curses-using application. If the application raises an exception, + this function will restore the terminal to a sane state before re-raising the + exception and generating a traceback. The callable object *func* is then passed + the main window 'stdscr' as its first argument, followed by any other arguments + passed to :func:`wrapper`. Before calling *func*, :func:`wrapper` turns on + cbreak mode, turns off echo, enables the terminal keypad, and initializes colors + if the terminal has color support. On exit (whether normally or by exception) + it restores cooked mode, turns on echo, and disables the terminal keypad. + + .. _curses-window-objects: Window Objects @@ -1665,33 +1674,3 @@ end of that line instead, and trailing blanks are stripped when the window contents are gathered. - -:mod:`curses.wrapper` --- Terminal handler for curses programs -============================================================== - -.. module:: curses.wrapper - :synopsis: Terminal configuration wrapper for curses programs. -.. moduleauthor:: Eric Raymond -.. sectionauthor:: Eric Raymond - - -.. versionadded:: 1.6 - -This module supplies one function, :func:`wrapper`, which runs another function -which should be the rest of your curses-using application. If the application -raises an exception, :func:`wrapper` will restore the terminal to a sane state -before re-raising the exception and generating a traceback. - - -.. function:: wrapper(func, ...) - - Wrapper function that initializes curses and calls another function, *func*, - restoring normal keyboard/screen behavior on error. The callable object *func* - is then passed the main window 'stdscr' as its first argument, followed by any - other arguments passed to :func:`wrapper`. - -Before calling the hook function, :func:`wrapper` turns on cbreak mode, turns -off echo, enables the terminal keypad, and initializes colors if the terminal -has color support. On exit (whether normally or by exception) it restores -cooked mode, turns on echo, and disables the terminal keypad. - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 01:42:46 2011 From: python-checkins at python.org (r.david.murray) Date: Sun, 19 Jun 2011 01:42:46 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzY3NzE6IGZpeCBk?= =?utf8?q?ocs=3A_curses=2Ewrapper_is_exposed_as_a_function=2C_not_a_module?= Message-ID: http://hg.python.org/cpython/rev/f9b4cfc19264 changeset: 70865:f9b4cfc19264 branch: 3.2 parent: 70862:3875ccea6367 user: R David Murray date: Sat Jun 18 19:34:12 2011 -0400 summary: #6771: fix docs: curses.wrapper is exposed as a function, not a module Patch by July Tikhonov. files: Doc/library/curses.rst | 46 ++++++++--------------------- 1 files changed, 13 insertions(+), 33 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -41,10 +41,6 @@ Module :mod:`curses.textpad` Editable text widget for curses supporting :program:`Emacs`\ -like bindings. - Module :mod:`curses.wrapper` - Convenience function to ensure proper terminal setup and resetting on - application entry and exit. - :ref:`curses-howto` Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. @@ -592,6 +588,19 @@ foreground color on the default background. +.. function:: wrapper(func, ...) + + Initialize curses and call another callable object, *func*, which should be the + rest of your curses-using application. If the application raises an exception, + this function will restore the terminal to a sane state before re-raising the + exception and generating a traceback. The callable object *func* is then passed + the main window 'stdscr' as its first argument, followed by any other arguments + passed to :func:`wrapper`. Before calling *func*, :func:`wrapper` turns on + cbreak mode, turns off echo, enables the terminal keypad, and initializes colors + if the terminal has color support. On exit (whether normally or by exception) + it restores cooked mode, turns on echo, and disables the terminal keypad. + + .. _curses-window-objects: Window Objects @@ -1659,32 +1668,3 @@ cursor motion that would land the cursor on a trailing blank goes to the end of that line instead, and trailing blanks are stripped when the window contents are gathered. - - -:mod:`curses.wrapper` --- Terminal handler for curses programs -============================================================== - -.. module:: curses.wrapper - :synopsis: Terminal configuration wrapper for curses programs. -.. moduleauthor:: Eric Raymond -.. sectionauthor:: Eric Raymond - - -This module supplies one function, :func:`wrapper`, which runs another function -which should be the rest of your curses-using application. If the application -raises an exception, :func:`wrapper` will restore the terminal to a sane state -before re-raising the exception and generating a traceback. - - -.. function:: wrapper(func, ...) - - Wrapper function that initializes curses and calls another function, *func*, - restoring normal keyboard/screen behavior on error. The callable object *func* - is then passed the main window 'stdscr' as its first argument, followed by any - other arguments passed to :func:`wrapper`. - -Before calling the hook function, :func:`wrapper` turns on cbreak mode, turns -off echo, enables the terminal keypad, and initializes colors if the terminal -has color support. On exit (whether normally or by exception) it restores -cooked mode, turns on echo, and disables the terminal keypad. - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 01:42:47 2011 From: python-checkins at python.org (r.david.murray) Date: Sun, 19 Jun 2011 01:42:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=236771=3A_fix_docs=3A_curses=2Ewrapper_is_exposed_as_?= =?utf8?q?a_function=2C_not_a_module?= Message-ID: http://hg.python.org/cpython/rev/bb5e950ebb04 changeset: 70866:bb5e950ebb04 parent: 70863:9569d8c4c781 parent: 70865:f9b4cfc19264 user: R David Murray date: Sat Jun 18 19:41:43 2011 -0400 summary: merge #6771: fix docs: curses.wrapper is exposed as a function, not a module files: Doc/library/curses.rst | 46 ++++++++--------------------- 1 files changed, 13 insertions(+), 33 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -41,10 +41,6 @@ Module :mod:`curses.textpad` Editable text widget for curses supporting :program:`Emacs`\ -like bindings. - Module :mod:`curses.wrapper` - Convenience function to ensure proper terminal setup and resetting on - application entry and exit. - :ref:`curses-howto` Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. @@ -592,6 +588,19 @@ foreground color on the default background. +.. function:: wrapper(func, ...) + + Initialize curses and call another callable object, *func*, which should be the + rest of your curses-using application. If the application raises an exception, + this function will restore the terminal to a sane state before re-raising the + exception and generating a traceback. The callable object *func* is then passed + the main window 'stdscr' as its first argument, followed by any other arguments + passed to :func:`wrapper`. Before calling *func*, :func:`wrapper` turns on + cbreak mode, turns off echo, enables the terminal keypad, and initializes colors + if the terminal has color support. On exit (whether normally or by exception) + it restores cooked mode, turns on echo, and disables the terminal keypad. + + .. _curses-window-objects: Window Objects @@ -1659,32 +1668,3 @@ cursor motion that would land the cursor on a trailing blank goes to the end of that line instead, and trailing blanks are stripped when the window contents are gathered. - - -:mod:`curses.wrapper` --- Terminal handler for curses programs -============================================================== - -.. module:: curses.wrapper - :synopsis: Terminal configuration wrapper for curses programs. -.. moduleauthor:: Eric Raymond -.. sectionauthor:: Eric Raymond - - -This module supplies one function, :func:`wrapper`, which runs another function -which should be the rest of your curses-using application. If the application -raises an exception, :func:`wrapper` will restore the terminal to a sane state -before re-raising the exception and generating a traceback. - - -.. function:: wrapper(func, ...) - - Wrapper function that initializes curses and calls another function, *func*, - restoring normal keyboard/screen behavior on error. The callable object *func* - is then passed the main window 'stdscr' as its first argument, followed by any - other arguments passed to :func:`wrapper`. - -Before calling the hook function, :func:`wrapper` turns on cbreak mode, turns -off echo, enables the terminal keypad, and initializes colors if the terminal -has color support. On exit (whether normally or by exception) it restores -cooked mode, turns on echo, and disables the terminal keypad. - -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 02:21:27 2011 From: python-checkins at python.org (r.david.murray) Date: Sun, 19 Jun 2011 02:21:27 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=236771=3A_Move_wrapper_fun?= =?utf8?q?ction_into_=5F=5Finit=5F=5F_and_eliminate_wrapper_module?= Message-ID: http://hg.python.org/cpython/rev/9c96c3adbcd1 changeset: 70867:9c96c3adbcd1 user: R David Murray date: Sat Jun 18 20:21:09 2011 -0400 summary: #6771: Move wrapper function into __init__ and eliminate wrapper module Andrew agreed in the issue that eliminating the module file made sense. Wrapper has only been exposed as a function, and so there is no (easy) way to access the wrapper module, which in any case only had the one function in it. Since __init__ already contains a couple wrapper functions, it seems to make sense to just move wrapper there instead of importing it from a single function module. files: Lib/curses/__init__.py | 46 +++++++++++++++++++++++++++- Lib/curses/wrapper.py | 50 ------------------------------ Misc/NEWS | 4 ++ 3 files changed, 49 insertions(+), 51 deletions(-) diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -13,7 +13,6 @@ __revision__ = "$Id$" from _curses import * -from curses.wrapper import wrapper import os as _os import sys as _sys @@ -57,3 +56,48 @@ has_key except NameError: from has_key import has_key + +# Wrapper for the entire curses-based application. Runs a function which +# should be the rest of your curses-based application. If the application +# raises an exception, wrapper() will restore the terminal to a sane state so +# you can read the resulting traceback. + +def wrapper(func, *args, **kwds): + """Wrapper function that initializes curses and calls another function, + restoring normal keyboard/screen behavior on error. + The callable object 'func' is then passed the main window 'stdscr' + as its first argument, followed by any other arguments passed to + wrapper(). + """ + + try: + # Initialize curses + stdscr = initscr() + + # Turn off echoing of keys, and enter cbreak mode, + # where no buffering is performed on keyboard input + noecho() + cbreak() + + # In keypad mode, escape sequences for special keys + # (like the cursor keys) will be interpreted and + # a special value like curses.KEY_LEFT will be returned + stdscr.keypad(1) + + # Start color, too. Harmless if the terminal doesn't have + # color; user can test with has_color() later on. The try/catch + # works around a minor bit of over-conscientiousness in the curses + # module -- the error return from C start_color() is ignorable. + try: + start_color() + except: + pass + + return func(stdscr, *args, **kwds) + finally: + # Set everything back to normal + if 'stdscr' in locals(): + stdscr.keypad(0) + echo() + nocbreak() + endwin() diff --git a/Lib/curses/wrapper.py b/Lib/curses/wrapper.py deleted file mode 100644 --- a/Lib/curses/wrapper.py +++ /dev/null @@ -1,50 +0,0 @@ -"""curses.wrapper - -Contains one function, wrapper(), which runs another function which -should be the rest of your curses-based application. If the -application raises an exception, wrapper() will restore the terminal -to a sane state so you can read the resulting traceback. - -""" - -import curses - -def wrapper(func, *args, **kwds): - """Wrapper function that initializes curses and calls another function, - restoring normal keyboard/screen behavior on error. - The callable object 'func' is then passed the main window 'stdscr' - as its first argument, followed by any other arguments passed to - wrapper(). - """ - - try: - # Initialize curses - stdscr = curses.initscr() - - # Turn off echoing of keys, and enter cbreak mode, - # where no buffering is performed on keyboard input - curses.noecho() - curses.cbreak() - - # In keypad mode, escape sequences for special keys - # (like the cursor keys) will be interpreted and - # a special value like curses.KEY_LEFT will be returned - stdscr.keypad(1) - - # Start color, too. Harmless if the terminal doesn't have - # color; user can test with has_color() later on. The try/catch - # works around a minor bit of over-conscientiousness in the curses - # module -- the error return from C start_color() is ignorable. - try: - curses.start_color() - except: - pass - - return func(stdscr, *args, **kwds) - finally: - # Set everything back to normal - if 'stdscr' in locals(): - stdscr.keypad(0) - curses.echo() - curses.nocbreak() - curses.endwin() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,10 @@ Library ------- +- Issue #6771: moved the curses.wrapper function from the single-function + wrapper module into __init__, eliminating the module. Since __init__ was + already importing the function to curses.wrapper, there is no API change. + - Issue #11584: email.header.decode_header no longer fails if the header passed to it is a Header object, and Header/make_header no longer fail if given binary unknown-8bit input. -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Sun Jun 19 05:06:07 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 19 Jun 2011 05:06:07 +0200 Subject: [Python-checkins] Daily reference leaks (9c96c3adbcd1): sum=300 Message-ID: results for 9c96c3adbcd1 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogh5lOqM', '-x'] From martin at v.loewis.de Sun Jun 19 13:07:14 2011 From: martin at v.loewis.de (=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=) Date: Sun, 19 Jun 2011 13:07:14 +0200 Subject: [Python-checkins] cpython: #11781: update windows build script to account for move of email tests In-Reply-To: <4DFD07EF.6060405@udel.edu> References: <4DFD07EF.6060405@udel.edu> Message-ID: <4DFDD862.9030709@v.loewis.de> >> # This should contain all non-.svn files listed in >> subversion > > Should this be mercurial Perhaps. > >> for f in os.listdir(lib.absolute): >> if f.endswith(".txt") or f==".svn":continue > > and this .hg? No. Martin From python-checkins at python.org Sun Jun 19 14:55:10 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 14:55:10 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Soften_the_tone_on_the_mai?= =?utf8?q?n_page_of_the_dev_guide_and_mention_the_core?= Message-ID: http://hg.python.org/devguide/rev/fbfa8b3e9663 changeset: 425:fbfa8b3e9663 parent: 416:779644152e5b user: Nick Coghlan date: Sun Jun 19 19:39:59 2011 +1000 summary: Soften the tone on the main page of the dev guide and mention the core mentorship program files: index.rst | 25 +++++++++++++++---------- 1 files changed, 15 insertions(+), 10 deletions(-) diff --git a/index.rst b/index.rst --- a/index.rst +++ b/index.rst @@ -50,18 +50,12 @@ ------------ We encourage everyone to contribute to Python and that's why we have put up -this developer's guide. You **should** read the following documents in -the order provided. You can stop where you feel comfortable and begin -contributing immediately without reading and understanding these documents all -at once, but please do not skip around within the documentation as everything -is written assuming preceding documentation has been read. - -You can, *however*, read the :doc:`FAQ ` at any point! +this developer's guide. If you still have questions after reviewing the +material in this guide, then the `Python Mentors`_ group is available to help +guide new contributors through the process. The :doc:`Developer FAQ ` is +another useful source of information. * :doc:`setup` -* Coding style guides - * `PEP 7`_ (Style Guide for C Code) - * `PEP 8`_ (Style Guide for Python Code) * :doc:`help` * :doc:`patch` * :doc:`runtests` @@ -82,6 +76,13 @@ * :doc:`devcycle` * :doc:`buildbots` +It is **recommended** that the above documents be read in the order listed. +You can stop where you feel comfortable and begin contributing immediately +without reading and understanding these documents all at once. If you do +choose to skip around within the documentation, be aware that it is written +assuming preceding documentation has been read so you may find it necessary +to backtrack to fill in missing concepts and terminology. + Proposing changes to Python itself ---------------------------------- @@ -99,6 +100,9 @@ * Anyone can checkout this guide from http://hg.python.org/devguide/. Core developers should use ssh://hg at hg.python.org/devguide instead, so that they can push back their edits to the server. +* Coding style guides + * `PEP 7`_ (Style Guide for C Code) + * `PEP 8`_ (Style Guide for Python Code) * `Issue tracker `_ * `Meta tracker `_ (issue tracker for the issue tracker) @@ -129,6 +133,7 @@ .. _PEP 7: http://www.python.org/dev/peps/pep-0007 .. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _python.org maintenance: http://python.org/dev/pydotorg/ +.. _Python Mentors: http://pythonmentors.com/ Indices and tables -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 14:55:14 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 14:55:14 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Add_a_devguide_category_in?= =?utf8?q?_the_interest_area_table_with_myself_and_Eric_Araujo?= Message-ID: http://hg.python.org/devguide/rev/93368fe55380 changeset: 426:93368fe55380 user: Nick Coghlan date: Sun Jun 19 19:57:06 2011 +1000 summary: Add a devguide category in the interest area table with myself and Eric Araujo as the initial members files: experts.rst | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/experts.rst b/experts.rst --- a/experts.rst +++ b/experts.rst @@ -296,6 +296,7 @@ context managers ncoghlan data formats mark.dickinson, georg.brandl database lemburg +devguide ncoghlan,eric.araujo documentation georg.brandl, ezio.melotti GUI i18n lemburg -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 14:55:16 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 14:55:16 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Mention_Python_Mentors_on_?= =?utf8?q?the_=27where_to_get_help=3F=27_page_=28closes_=2312278=2C_patch?= Message-ID: http://hg.python.org/devguide/rev/cbbc4fab52d8 changeset: 427:cbbc4fab52d8 user: Nick Coghlan date: Sun Jun 19 19:59:15 2011 +1000 summary: Mention Python Mentors on the 'where to get help?' page (closes #12278, patch courtesy of Adam Woodbeck) files: help.rst | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) diff --git a/help.rst b/help.rst --- a/help.rst +++ b/help.rst @@ -17,7 +17,7 @@ You have two avenues of communication out of the :ref:`myriad of options available `. If you are comfortable with IRC you can try asking on ``#python-dev`` (on the `freenode `_ network). -Typically there are a couple of experienced developers, ranging from +Typically there are a variety of experienced developers, ranging from triagers to core developers, who can answer questions about developing for Python. If you prefer email you can ask the `python-dev mailing-list `_ for help with your @@ -37,3 +37,15 @@ .. _issue tracker: http://bugs.python.org + +Core Mentorship +--------------- + +If you are interested in improving Python and contributing to its development, +but don't yet feel entirely comfortable with the public channels mentioned +above `Python Mentors`_ are here to help you. Python is fortunate to have a +community of volunteer developers willing to mentor anyone wishing to +contribute code, work on bug fixes or improve documentation. Everyone is +welcomed and encouraged to contribute. + +.. _Python Mentors: http://pythonmentors.com -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 14:55:17 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 14:55:17 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Make_the_scope_of_the_devg?= =?utf8?q?uide_explicit_on_the_main_page_and_refer_to_other?= Message-ID: http://hg.python.org/devguide/rev/fabcea815a19 changeset: 428:fabcea815a19 user: Nick Coghlan date: Sun Jun 19 20:07:28 2011 +1000 summary: Make the scope of the devguide explicit on the main page and refer to other implementations files: index.rst | 39 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 39 insertions(+), 0 deletions(-) diff --git a/index.rst b/index.rst --- a/index.rst +++ b/index.rst @@ -55,6 +55,8 @@ guide new contributors through the process. The :doc:`Developer FAQ ` is another useful source of information. +Guide for contributing to Python: + * :doc:`setup` * :doc:`help` * :doc:`patch` @@ -87,10 +89,43 @@ Proposing changes to Python itself ---------------------------------- +Improving Python's code, documentation and tests are ongoing tasks that are +never going to be "finished", as Python operates as part of an ever-evolving +system of technology. An even more challenging ongoing task than these +necessary maintenance activities is finding ways to make Python, in the form +of the standard library and the language definition, an even better tool in a +developer's toolkit. + +While these kinds of change are much rarer than those described above, they do +happen and that process is also described as part of this guide: + * :doc:`stdlibchanges` * :doc:`langchanges` +Other Interpreter Implementations +--------------------------------- + +This guide is specifically for contributing to the Python reference +interpreter, also known as CPython (while most of the standard library is +written in Python, the interpreter core is written in C and integrates most +easily with the C and C++ ecosystems). + +There are other Python implementations, each with a different focus. +Like CPython, they always have more things they would like to do than they +have developers to work on them. Some major example that may of interest are: + +* PyPy_: A Python interpreter focused on high speed (JIT-compiled) operation + on major platforms +* Jython_: A Python interpreter focused on good integration with the Java + Virtual Machine (JVM) environment +* IronPython_: A Python interpreter focused on good integration with the + Common Language Runtime (CLR) provided by .NET and Mono +* Stackless_: A Python interpreter focused on providing lightweight + microthreads while remaining largely compatible with CPython specific + extension modules + + .. _resources: @@ -134,6 +169,10 @@ .. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _python.org maintenance: http://python.org/dev/pydotorg/ .. _Python Mentors: http://pythonmentors.com/ +.. _PyPy: http://www.pypy.org/ +.. _Jython: http://www.jython.org/ +.. _IronPython: http://ironpython.net/ +.. _Stackless: http://www.stackless.com/ Indices and tables -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 14:55:20 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 14:55:20 +0200 Subject: [Python-checkins] =?utf8?q?devguide_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Merge_with_head?= Message-ID: http://hg.python.org/devguide/rev/986ea2e2798b changeset: 429:986ea2e2798b parent: 428:fabcea815a19 parent: 424:fe159fa6166f user: Nick Coghlan date: Sun Jun 19 22:54:41 2011 +1000 summary: Merge with head files: developers.rst | 4 ++++ experts.rst | 23 +++++++++++++---------- index.rst | 2 +- triaging.rst | 5 +++++ 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/developers.rst b/developers.rst --- a/developers.rst +++ b/developers.rst @@ -24,6 +24,10 @@ Permissions History ------------------- +- Charles-Fran?ois Natali was given push privileges on May 19 2011 by Antoine + Pitrou, for general contributions, on recommandation by Victor Stinner, + Brian Curtin and others. + - Nadeem Vawda was given push privileges on Apr 10 2011 by GFB, for general contributions, on recommendation by Antoine Pitrou. diff --git a/experts.rst b/experts.rst --- a/experts.rst +++ b/experts.rst @@ -17,6 +17,8 @@ that person, only make them nosy. Names followed by a '*' may be assigned issues involving the module or topic. +.. TODO document automatic assignment/nosy: people need not add them manually + The Platform and Interest Area tables list broader fields in which various people have expertise. These people can also be contacted for help, opinions, and decisions when issues involve their areas. @@ -45,7 +47,7 @@ Module Maintainers ==================== ============================================= __future__ -__main__ gvanrossum,ncoghlan +__main__ gvanrossum, ncoghlan _dummy_thread brett.cannon _thread pitrou abc @@ -128,7 +130,7 @@ inspect io pitrou, benjamin.peterson, stutzbach itertools rhettinger -json bob.ippolito (inactive), rhettinger +json bob.ippolito (inactive), ezio.melotti, rhettinger keyword lib2to3 benjamin.peterson linecache @@ -153,6 +155,7 @@ optparse aronacher os loewis ossaudiodev +packaging tarek*, eric.araujo*, alexis parser pdb georg.brandl* pickle alexandre.vassalotti, pitrou @@ -296,25 +299,25 @@ context managers ncoghlan data formats mark.dickinson, georg.brandl database lemburg -devguide ncoghlan,eric.araujo -documentation georg.brandl, ezio.melotti +devguide ncoghlan, eric.araujo +documentation georg.brandl, ezio.melotti, eric.araujo GUI -i18n lemburg +i18n lemburg, eric.araujo import machinery brett.cannon, ncoghlan io pitrou, benjamin.peterson, stutzbach locale lemburg, loewis mathematics mark.dickinson, eric.smith, lemburg, stutzbach memory management tim_one, lemburg networking giampaolo.rodola -packaging tarek, lemburg, alexis +packaging tarek, lemburg, alexis, eric.araujo py3 transition benjamin.peterson release management tarek, lemburg, benjamin.peterson, barry, loewis, - gvanrossum, anthonybaxter + gvanrossum, anthonybaxter, eric.araujo str.format eric.smith -testing michael.foord, pitrou, giampaolo.rodola, ezio.melotti -test coverage ncoghlan +testing michael.foord, pitrou, ezio.melotti +test coverage ncoghlan, giampaolo.rodola threads pitrou time and dates lemburg, belopolsky unicode lemburg, ezio.melotti, haypo -version control +version control eric.araujo ================== =========== diff --git a/index.rst b/index.rst --- a/index.rst +++ b/index.rst @@ -37,7 +37,7 @@ Quick Links ----------- -Here are some links that you may find you refererence frequently while +Here are some links that you may find you reference frequently while contributing to Python. * `Issue tracker `_ diff --git a/triaging.rst b/triaging.rst --- a/triaging.rst +++ b/triaging.rst @@ -206,6 +206,11 @@ :abbr:`VCS (version control system)` to Mercurial. The issue tracker automatically translates the legacy svn revision ```` to its corresponding Mercurial changeset identifier. +* ``Dir/file.ext`` and ``Dir/file.ext:NNN`` generate links to files in the + `Python source code repositories `_, + possibly linking to the line number specified after the ``:``. +* ``PEP `` and ``PEP`` link to the + :abbr:`PEP (Python Enhancement Proposal)` ````. Reporting Issues About the Tracker -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 15:07:59 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 15:07:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_ACKS_update_for_devguide_pa?= =?utf8?q?tch_=28closes_=2312278=29?= Message-ID: http://hg.python.org/cpython/rev/144b12d7bb28 changeset: 70868:144b12d7bb28 user: Nick Coghlan date: Sun Jun 19 23:07:49 2011 +1000 summary: ACKS update for devguide patch (closes #12278) files: Misc/ACKS | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1013,6 +1013,7 @@ Klaus-Juergen Wolf Dan Wolfe Richard Wolff +Adam Woodbeck Darren Worrall Gordon Worley Thomas Wouters -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 16:07:14 2011 From: python-checkins at python.org (victor.stinner) Date: Sun, 19 Jun 2011 16:07:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_faulthandler_doc=3A_the_the?= =?utf8?q?_=3D=3E_the?= Message-ID: http://hg.python.org/cpython/rev/0eec89955a2f changeset: 70869:0eec89955a2f user: Victor Stinner date: Sun Jun 19 16:07:20 2011 +0200 summary: faulthandler doc: the the => the files: Doc/library/faulthandler.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -24,7 +24,7 @@ * Only ASCII is supported. The ``backslashreplace`` error handler is used on encoding. * Each string is limited to 100 characters. -* Only the the filename, the function name and the line number are +* Only the filename, the function name and the line number are displayed. (no source code) * It is limited to 100 frames and 100 threads. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 16:34:33 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Jun 2011 16:34:33 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_clarify?= Message-ID: http://hg.python.org/cpython/rev/29517ee4919d changeset: 70870:29517ee4919d parent: 70855:f041d2223ed3 user: Benjamin Peterson date: Sun Jun 19 09:37:18 2011 -0500 summary: clarify files: Doc/library/faulthandler.rst | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -43,9 +43,8 @@ .. function:: dump_traceback(file=sys.stderr, all_threads=True) - Dump the traceback of all threads into *file*. If *all_threads* is ``True``, - produce tracebacks for every running thread. Otherwise, dump only the current - thread. + Dump the tracebacks of all threads into *file*. If *all_threads* is + ``False``, dump only the current thread. Fault handler state @@ -77,9 +76,10 @@ Dump the tracebacks of all threads, after a timeout of *timeout* seconds, or every *timeout* seconds if *repeat* is ``True``. If *exit* is ``True``, call :c:func:`_exit` with status=1 after dumping the tracebacks. (Note - :c:func:`_exit` doesn't flush file buffers.) If the function is called twice, - the new call replaces previous parameters and resets the timeout. The timer - has a sub-second resolution. + :c:func:`_exit` exits the process immediately, which means it doesn't do any + cleanup like flushing file buffers.) If the function is called twice, the new + call replaces previous parameters and resets the timeout. The timer has a + sub-second resolution. This function is implemented using a watchdog thread and therefore is not available if Python is compiled with threads disabled. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 16:34:35 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 19 Jun 2011 16:34:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/a7e00934baf1 changeset: 70871:a7e00934baf1 parent: 70870:29517ee4919d parent: 70869:0eec89955a2f user: Benjamin Peterson date: Sun Jun 19 09:38:02 2011 -0500 summary: merge heads files: Doc/library/curses.rst | 46 ++++------------ Doc/library/faulthandler.rst | 2 +- Lib/curses/__init__.py | 46 +++++++++++++++++- Lib/curses/wrapper.py | 50 ------------------- Lib/email/header.py | 10 ++- Lib/mailbox.py | 14 +++- Lib/test/test_email/test_email.py | 17 ++++++- Lib/test/test_mailbox.py | 13 ++++- Misc/ACKS | 1 + Misc/NEWS | 11 ++++ Tools/msi/msi.py | 4 +- 11 files changed, 118 insertions(+), 96 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -41,10 +41,6 @@ Module :mod:`curses.textpad` Editable text widget for curses supporting :program:`Emacs`\ -like bindings. - Module :mod:`curses.wrapper` - Convenience function to ensure proper terminal setup and resetting on - application entry and exit. - :ref:`curses-howto` Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. @@ -592,6 +588,19 @@ foreground color on the default background. +.. function:: wrapper(func, ...) + + Initialize curses and call another callable object, *func*, which should be the + rest of your curses-using application. If the application raises an exception, + this function will restore the terminal to a sane state before re-raising the + exception and generating a traceback. The callable object *func* is then passed + the main window 'stdscr' as its first argument, followed by any other arguments + passed to :func:`wrapper`. Before calling *func*, :func:`wrapper` turns on + cbreak mode, turns off echo, enables the terminal keypad, and initializes colors + if the terminal has color support. On exit (whether normally or by exception) + it restores cooked mode, turns on echo, and disables the terminal keypad. + + .. _curses-window-objects: Window Objects @@ -1659,32 +1668,3 @@ cursor motion that would land the cursor on a trailing blank goes to the end of that line instead, and trailing blanks are stripped when the window contents are gathered. - - -:mod:`curses.wrapper` --- Terminal handler for curses programs -============================================================== - -.. module:: curses.wrapper - :synopsis: Terminal configuration wrapper for curses programs. -.. moduleauthor:: Eric Raymond -.. sectionauthor:: Eric Raymond - - -This module supplies one function, :func:`wrapper`, which runs another function -which should be the rest of your curses-using application. If the application -raises an exception, :func:`wrapper` will restore the terminal to a sane state -before re-raising the exception and generating a traceback. - - -.. function:: wrapper(func, ...) - - Wrapper function that initializes curses and calls another function, *func*, - restoring normal keyboard/screen behavior on error. The callable object *func* - is then passed the main window 'stdscr' as its first argument, followed by any - other arguments passed to :func:`wrapper`. - -Before calling the hook function, :func:`wrapper` turns on cbreak mode, turns -off echo, enables the terminal keypad, and initializes colors if the terminal -has color support. On exit (whether normally or by exception) it restores -cooked mode, turns on echo, and disables the terminal keypad. - diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -24,7 +24,7 @@ * Only ASCII is supported. The ``backslashreplace`` error handler is used on encoding. * Each string is limited to 100 characters. -* Only the the filename, the function name and the line number are +* Only the filename, the function name and the line number are displayed. (no source code) * It is limited to 100 frames and 100 threads. diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -13,7 +13,6 @@ __revision__ = "$Id$" from _curses import * -from curses.wrapper import wrapper import os as _os import sys as _sys @@ -57,3 +56,48 @@ has_key except NameError: from has_key import has_key + +# Wrapper for the entire curses-based application. Runs a function which +# should be the rest of your curses-based application. If the application +# raises an exception, wrapper() will restore the terminal to a sane state so +# you can read the resulting traceback. + +def wrapper(func, *args, **kwds): + """Wrapper function that initializes curses and calls another function, + restoring normal keyboard/screen behavior on error. + The callable object 'func' is then passed the main window 'stdscr' + as its first argument, followed by any other arguments passed to + wrapper(). + """ + + try: + # Initialize curses + stdscr = initscr() + + # Turn off echoing of keys, and enter cbreak mode, + # where no buffering is performed on keyboard input + noecho() + cbreak() + + # In keypad mode, escape sequences for special keys + # (like the cursor keys) will be interpreted and + # a special value like curses.KEY_LEFT will be returned + stdscr.keypad(1) + + # Start color, too. Harmless if the terminal doesn't have + # color; user can test with has_color() later on. The try/catch + # works around a minor bit of over-conscientiousness in the curses + # module -- the error return from C start_color() is ignorable. + try: + start_color() + except: + pass + + return func(stdscr, *args, **kwds) + finally: + # Set everything back to normal + if 'stdscr' in locals(): + stdscr.keypad(0) + echo() + nocbreak() + endwin() diff --git a/Lib/curses/wrapper.py b/Lib/curses/wrapper.py deleted file mode 100644 --- a/Lib/curses/wrapper.py +++ /dev/null @@ -1,50 +0,0 @@ -"""curses.wrapper - -Contains one function, wrapper(), which runs another function which -should be the rest of your curses-based application. If the -application raises an exception, wrapper() will restore the terminal -to a sane state so you can read the resulting traceback. - -""" - -import curses - -def wrapper(func, *args, **kwds): - """Wrapper function that initializes curses and calls another function, - restoring normal keyboard/screen behavior on error. - The callable object 'func' is then passed the main window 'stdscr' - as its first argument, followed by any other arguments passed to - wrapper(). - """ - - try: - # Initialize curses - stdscr = curses.initscr() - - # Turn off echoing of keys, and enter cbreak mode, - # where no buffering is performed on keyboard input - curses.noecho() - curses.cbreak() - - # In keypad mode, escape sequences for special keys - # (like the cursor keys) will be interpreted and - # a special value like curses.KEY_LEFT will be returned - stdscr.keypad(1) - - # Start color, too. Harmless if the terminal doesn't have - # color; user can test with has_color() later on. The try/catch - # works around a minor bit of over-conscientiousness in the curses - # module -- the error return from C start_color() is ignorable. - try: - curses.start_color() - except: - pass - - return func(stdscr, *args, **kwds) - finally: - # Set everything back to normal - if 'stdscr' in locals(): - stdscr.keypad(0) - curses.echo() - curses.nocbreak() - curses.endwin() diff --git a/Lib/email/header.py b/Lib/email/header.py --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -73,9 +73,10 @@ An email.errors.HeaderParseError may be raised when certain decoding error occurs (e.g. a base64 decoding exception). """ - # If it is a Header object, we can just return the chunks. + # If it is a Header object, we can just return the encoded chunks. if hasattr(header, '_chunks'): - return list(header._chunks) + return [(_charset._encode(string, str(charset)), str(charset)) + for string, charset in header._chunks] # If no encoding, just return the header with no charset. if not ecre.search(header): return [(header, None)] @@ -274,7 +275,10 @@ charset = Charset(charset) if not isinstance(s, str): input_charset = charset.input_codec or 'us-ascii' - s = s.decode(input_charset, errors) + if input_charset == _charset.UNKNOWN8BIT: + s = s.decode('us-ascii', 'surrogateescape') + else: + s = s.decode(input_charset, errors) # Ensure that the bytes we're storing can be decoded to the output # character set, otherwise an early error is thrown. output_charset = charset.output_codec or 'us-ascii' diff --git a/Lib/mailbox.py b/Lib/mailbox.py --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1923,9 +1923,10 @@ def close(self): """Close the file.""" - if hasattr(self._file, 'close'): - self._file.close() - del self._file + if hasattr(self, '_file'): + if hasattr(self._file, 'close'): + self._file.close() + del self._file def _read(self, size, read_method): """Read size bytes using read_method.""" @@ -1957,6 +1958,10 @@ @property def closed(self): + if not hasattr(self, '_file'): + return True + if not hasattr(self._file, 'closed'): + return False return self._file.closed @@ -1995,7 +2000,8 @@ def close(self): # do *not* close the underlying file object for partial files, # since it's global to the mailbox object - del self._file + if hasattr(self, '_file'): + del self._file def _lock_file(f, dotlock=True): diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -4324,12 +4324,27 @@ def test_escaped_8bit_header(self): x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' - x = x.decode('ascii', 'surrogateescape') + e = x.decode('ascii', 'surrogateescape') + h = Header(e, charset=email.charset.UNKNOWN8BIT) + self.assertEqual(str(h), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + + def test_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' h = Header(x, charset=email.charset.UNKNOWN8BIT) self.assertEqual(str(h), 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') self.assertEqual(email.header.decode_header(h), [(x, 'unknown-8bit')]) + def test_make_header_handles_binary_unknown8bit(self): + x = b'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' + h = Header(x, charset=email.charset.UNKNOWN8BIT) + h2 = email.header.make_header(email.header.decode_header(h)) + self.assertEqual(str(h2), + 'Ynwp4dUEbay Auction Semiar- No Charge \uFFFD Earn Big') + self.assertEqual(email.header.decode_header(h2), [(x, 'unknown-8bit')]) + def test_modify_returned_list_does_not_change_header(self): h = Header('test') chunks = email.header.decode_header(h) diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -297,6 +297,13 @@ self.assertEqual(data1.decode('ascii').replace(os.linesep, '\n'), _sample_message) + def test_get_file_can_be_closed_twice(self): + # Issue 11700 + key = self._box.add(_sample_message) + f = self._box.get_file(key) + f.close() + f.close() + def test_iterkeys(self): # Get keys using iterkeys() self._check_iteration(self._box.keys, do_keys=True, do_values=False) @@ -1862,8 +1869,12 @@ def _test_close(self, proxy): # Close a file + self.assertFalse(proxy.closed) proxy.close() - self.assertRaises(AttributeError, lambda: proxy.close()) + self.assertTrue(proxy.closed) + # Issue 11700 subsequent closes should be a no-op. + proxy.close() + self.assertTrue(proxy.closed) class TestProxyFile(TestProxyFileBase): diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1013,6 +1013,7 @@ Klaus-Juergen Wolf Dan Wolfe Richard Wolff +Adam Woodbeck Darren Worrall Gordon Worley Thomas Wouters diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,6 +193,17 @@ Library ------- +- Issue #6771: moved the curses.wrapper function from the single-function + wrapper module into __init__, eliminating the module. Since __init__ was + already importing the function to curses.wrapper, there is no API change. + +- Issue #11584: email.header.decode_header no longer fails if the header + passed to it is a Header object, and Header/make_header no longer fail + if given binary unknown-8bit input. + +- Issue #11700: mailbox proxy object close methods can now be called multiple + times without error. + - Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. - Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1057,14 +1057,14 @@ lib.add_file("turtle.cfg") if dir=="pydoc_data": lib.add_file("_pydoc.css") - if dir=="data" and parent.physical=="test" and parent.basedir.physical=="email": + if dir=="data" and parent.physical=="test_email": # This should contain all non-.svn files listed in subversion for f in os.listdir(lib.absolute): if f.endswith(".txt") or f==".svn":continue if f.endswith(".au") or f.endswith(".gif"): lib.add_file(f) else: - print("WARNING: New file %s in email/test/data" % f) + print("WARNING: New file %s in test/test_email/data" % f) for f in os.listdir(lib.absolute): if os.path.isdir(os.path.join(lib.absolute, f)): pydirs.append((lib, f)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 16:51:50 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 16:51:50 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Update_the_committing_page?= =?utf8?q?_with_various_details_=28closes_=2311795=2C_but_also?= Message-ID: http://hg.python.org/devguide/rev/774fb024b152 changeset: 430:774fb024b152 user: Nick Coghlan date: Mon Jun 20 00:04:06 2011 +1000 summary: Update the committing page with various details (closes #11795, but also includes additional Hg tips) files: committing.rst | 104 +++++++++++++++++++++++++++++++++--- 1 files changed, 94 insertions(+), 10 deletions(-) diff --git a/committing.rst b/committing.rst --- a/committing.rst +++ b/committing.rst @@ -3,8 +3,29 @@ Committing and Pushing Changes ============================== -.. TODO: include a checklist of items to be included in a commit? - e.g updated Misc/NEWS entry, tests, doc +Patch Checklist +--------------- + +Here's the simple patch checklist that ``make patchcheck`` will run through +on a system that uses the makefile to build Python: + +* Are there any whitespace problems in Python files? + (using Tools/scripts/reindent.py) +* Are there any whitespace problems in C files? +* Are there any whitespace problems in the documentation? + (using Tools/scripts/reindent-rst.py) +* Has the documentation been updated? +* Has the test suite been updated? +* Has ``Misc/ACKS`` been updated? +* Has ``Misc/ACKS`` been updated? +* Has the test suite been run? + +Note that the automated patch check can't actually *answer* all of these +questions, and even if it could, it still wouldn't know whether or not +those answers were appropriate. Aside from the whitespace checks, it is just +a memory aid to help with remembering the various elements that can go into +making a complete patch. + Commit Messages --------------- @@ -54,6 +75,10 @@ such as mq_ (Mercurial Queues), in order to maintain patches in a single local repository and to push them seamlessly when they are ready. +It can also be useful to keep a pristine clone of the main repository around, +as it allows simple reversion of all local changes (even "committed" ones) if +your local clone gets into a state you aren't happy with. + .. _Mercurial: http://www.hg-scm.org/ .. _mq: http://mercurial.selenic.com/wiki/MqExtension @@ -119,6 +144,41 @@ **will** break someone's code). If you are unsure if the breakage is worth it, ask on python-dev. +Third, ensure the patch is attributed correctly by adding the contributor's +name to ``Misc/ACKS`` if they aren't already there (and didn't add themselves +in their patch) and by mentioning "Patch by " in the ``Misc/NEWS`` entry +and the checkin message. If the patch has been heavily modified then "Initial +patch by " is an appropriate alternate wording. + +If you omit correct attribution in the initial checkin, then update ``ACKS`` +and ``NEWS`` in a subsequent checkin (don't worry about trying to fix the +original checkin message in that case). + + +Contributor Licensing Agreements +-------------------------------- + +It's unlikely bug fixes will require a `Contributor Licensing Agreement`_ +unless they touch a *lot* of code. For new features, it is preferable to +ask that the contributor submit a signed CLA to the PSF as the associated +comments, docstrings and documentation are far more likely to reach a +copyrightable standard. + +For Python sprints we now recommend collecting CLAs as a matter of course, as +the folks leading the sprints can then handle the task of scanning (or otherwise +digitising) the forms and passing them on to the PSF secretary. (Yes, we +realise this process is quite archaic. Yes, we're in the process of fixing +it. No, it's not fixed yet). + +As discussed on the PSF Contribution_ page, it is the CLA itself that gives +the PSF the necessary relicensing rights to redistribute contributions under +the Python license stack. This is an additional permission granted above and +beyond the normal permissions provided by the chosen open source license. + +.. _Contribution: http://www.python.org/psf/contrib/ +.. _Contributor Licensing Agreement: + http://www.python.org/psf/contrib/contrib-form/ + Forward-Porting --------------- @@ -135,7 +195,7 @@ Even when porting an already committed patch, you should **still** check the test suite runs successfully before committing the patch to another branch. Subtle differences between two branches sometimes make a patch bogus if - ported straightly. + ported without any modifications. Porting Within a Major Version @@ -222,8 +282,8 @@ There are various ways to achieve this, but here is a possible scenario: -* First do a clone of the public repository, whose working copy will be updated - to the ``default`` branch:: +* First do a clone of the public repository, whose working copy will be + updated to the ``default`` branch:: $ hg clone ssh://hg at hg.python.org/cpython py3k @@ -234,10 +294,11 @@ $ cd py3.2 $ hg update 3.2 -* If you also need the 3.1 branch, you can similarly clone it, either from - the ``py3.2`` or the ``py3k`` repository. It is suggested, though, that you - clone from ``py3.2`` as that it will force you to push changes back up your - clone chain so that you make sure to port changes to all proper versions. +* If you also need the 3.1 branch to work on security fixes, you can similarly + clone it, either from the ``py3.2`` or the ``py3k`` repository. It is + suggested, though, that you clone from ``py3.2`` as that it will force you + to push changes back up your clone chain so that you make sure to port + changes to all proper versions. * You can also clone a 2.7-dedicated repository from the ``py3k`` branch:: @@ -253,8 +314,25 @@ from the ``py3k`` repository will publish your changes in the public repository. +When working with this kind of arrangement, it can be useful to have a simple +script that runs the necessary commands to update all branches with upstream +changes:: + + cd ~/py3k + hg pull -u + cd ~/py3.2 + hg pull -u + cd ~/py2.7 + hg pull -u + +Only the first of those updates will touch the network - the latter two will +just transfer the changes locally between the relevant repositories. + If you want, you can later :ref:`change the flow of changes ` implied -by the cloning of repositories. +by the cloning of repositories. For example, you may choose to add a separate +``sandbox`` repository for experimental code (potentially published somewhere +other than python.org) or an additional pristine repository that is +never modified locally. Differences with ``svnmerge`` @@ -354,8 +432,14 @@ mywork $ hg merge default +Rather than using a clone on ``python.org`` (which isn't particularly useful +for collaboration with folks that don't already have CPython commit rights), +Bitbucket_ also maintain an `up to date clone`_ of the main ``cpython`` +repository that can be used as the basis for a new clone or patch queue. .. _named branch: http://mercurial.selenic.com/wiki/NamedBranches +.. _Bitbucket: http://www.bitbucket.org +.. _up to date clone: https://bitbucket.org/mirror/cpython/overview Uploading a patch for review -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 16:51:53 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 16:51:53 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Add_a_communications_secti?= =?utf8?q?on_to_the_devguide_FAQ_=28closes_=2311690=29?= Message-ID: http://hg.python.org/devguide/rev/f1ebfb53437f changeset: 431:f1ebfb53437f user: Nick Coghlan date: Mon Jun 20 00:46:57 2011 +1000 summary: Add a communications section to the devguide FAQ (closes #11690) files: faq.rst | 102 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 101 insertions(+), 1 deletions(-) diff --git a/faq.rst b/faq.rst --- a/faq.rst +++ b/faq.rst @@ -8,8 +8,108 @@ .. contents:: :local: + +Communications +============== + + +Where should I ask general Python questions? +-------------------------------------------- + +General Python questions should still go to `python-list`_ or `python-tutor`_ +or similar resources, such as StackOverflow_ or ``#python`` on IRC. + +.. _python-list: http://mail.python.org/mailman/listinfo/python-list +.. _python-tutor: http://mail.python.org/mailman/listinfo/python-tutor +.. _StackOverflow: http://stackoverflow.com/ + + +Where should I suggest new features and language changes? +--------------------------------------------------------- + +The `python-ideas`_ mailing list is specifically intended for discussion of +new features and language changes. Please don't be disappointed if your +idea isn't met with universal approval: as the long list of Rejected and +Withdrawn PEPs in the `PEP Index`_ attests, and as befits a reasonably mature +programming language, getting significant changes into Python isn't a simple +task. + +If the idea is reasonable, someone will suggest posting it as a feature +request on the `issue tracker`_. + +.. _python-ideas: http://mail.python.org/mailman/listinfo/python-ideas +.. _issue tracker: http://bugs.python.org +.. _PEP Index: http://www.python.org/dev/peps + + +Where should I ask general questions about contributing to CPython? +------------------------------------------------------------------- + +The `Python Mentors`_ program is specifically about encouraging +developers and others that would like to contribute to Python development in +general, rather than necessarily being focused on one particular issue. + +.. _Python Mentors: http://pythonmentors.com + + +Where should I report specific problems? +---------------------------------------- + +Specific problems should be posted to the `issue tracker`_. + + +What if I'm not sure it is a bug? +--------------------------------- + +The general Python help locations listed above are the best place to start +with that kind of question. If they agree it looks like a bug, then the +next step is to either post it to the `issue tracker`_ or else to ask further +on the core development mailing list, `python-dev`_. + +.. _python-dev: http://mail.python.org/mailman/listinfo/python-dev + + +What if I disagree with an issue resolution on the tracker? +----------------------------------------------------------- + +First, take some time to consider any comments made in association with the +resolution of the tracker issue. On reflection, they may seem more reasonable +than they first appeared. + +If you still feel the resolution is incorrect, then raise the question on +`python-dev`_. If the consensus there supports the disputed resolution, please +take any further objections to `python-ideas`_ (or some other forum). Further +argument on `python-dev`_ after a consensus has been reached amongst the core +developers is unlikely to win any converts. + + +How do I tell who is and isn't a core developer? +------------------------------------------------ + +You can check their name against the `full list of developers`_ with commit +rights to the main source control repository. + +On the `issue tracker`_, most core developers will have the Python logo +appear next to their name. + +.. _full list of developers: http://www.python.org/dev/committers + + +What standards of behaviour are expected in these communication channels? +------------------------------------------------------------------------- + +We try to foster environments of mutual respect, tolerance and encouragement, +as described in the PSF's `Diversity Statement`_. Abiding by the guidelines +in this document and asking questions or posting suggestions in the +appropriate channels are an excellent way to get started on the mutual respect +part, greatly increasing the chances of receiving tolerance and encouragement +in return. + +.. _Diversity Statement: http://www.python.org/psf/diversity/ + + Version Control -================================== +=============== Where can I learn about the version control system used, Mercurial (hg)? ------------------------------------------------------------------------------- -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 16:51:54 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 19 Jun 2011 16:51:54 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Add_note_about_the_dev_gui?= =?utf8?q?de_itself_to_the_doc_quality_page?= Message-ID: http://hg.python.org/devguide/rev/5ab42baba771 changeset: 432:5ab42baba771 user: Nick Coghlan date: Mon Jun 20 00:51:44 2011 +1000 summary: Add note about the dev guide itself to the doc quality page files: docquality.rst | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/docquality.rst b/docquality.rst --- a/docquality.rst +++ b/docquality.rst @@ -66,3 +66,13 @@ to finish, filing issues in the issue tracker for each problem you find. Don't file a single issue for an entire section containing multiple problems as that makes it harder to break the work up for multiple people to help with. + + +Helping with the Developer's Guide +---------------------------------- + +This developer guide lives in a `separate source code repository`_, but is +otherwise managed using the same process as is used for the main Python +documentation. + +.. _separate source code repository: http://hg.python.org/devguide -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 16:56:21 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 16:56:21 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Use_built-in_reST_roles_fo?= =?utf8?q?r_PEP_links?= Message-ID: http://hg.python.org/devguide/rev/8eb739687196 changeset: 433:8eb739687196 user: ?ric Araujo date: Sun Jun 19 16:51:30 2011 +0200 summary: Use built-in reST roles for PEP links files: index.rst | 6 ++---- patch.rst | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/index.rst b/index.rst --- a/index.rst +++ b/index.rst @@ -136,8 +136,8 @@ Core developers should use ssh://hg at hg.python.org/devguide instead, so that they can push back their edits to the server. * Coding style guides - * `PEP 7`_ (Style Guide for C Code) - * `PEP 8`_ (Style Guide for Python Code) + * :PEP:`7` (Style Guide for C Code) + * :PEP:`8` (Style Guide for Python Code) * `Issue tracker `_ * `Meta tracker `_ (issue tracker for the issue tracker) @@ -165,8 +165,6 @@ .. _Firefox search engine plug-in: http://www.python.org/dev/searchplugin/ .. _Misc directory: http://hg.python.org/cpython/file/tip/Misc .. _PEPs: http://www.python.org/dev/peps -.. _PEP 7: http://www.python.org/dev/peps/pep-0007 -.. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _python.org maintenance: http://python.org/dev/pydotorg/ .. _Python Mentors: http://pythonmentors.com/ .. _PyPy: http://www.pypy.org/ diff --git a/patch.rst b/patch.rst --- a/patch.rst +++ b/patch.rst @@ -69,7 +69,7 @@ do to help ensure that your patch is accepted. First, make sure to follow Python's style guidelines. For Python code you -should follow `PEP 8`_, and for C code you should follow `PEP 7`_. If you have +should follow :PEP:`8`, and for C code you should follow :PEP:`7`. If you have one or two discrepencies those can be fixed by the core developer who commits your patch. But if you have systematic deviations from the style guides your patch will be put on hold until you fix the formatting issues. @@ -104,8 +104,6 @@ .. _contributor form: http://www.python.org/psf/contrib/ -.. _PEP 7: http://www.python.org/dev/peps/pep-0007 -.. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _Python Software Foundation: http://www.python.org/psf/ -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Sun Jun 19 16:57:03 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 16:57:03 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Fix_copy-paste_glitch_=3A?= =?utf8?q?=29?= Message-ID: http://hg.python.org/devguide/rev/f55ad3dc4526 changeset: 434:f55ad3dc4526 user: ?ric Araujo date: Sun Jun 19 16:56:58 2011 +0200 summary: Fix copy-paste glitch :) files: committing.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/committing.rst b/committing.rst --- a/committing.rst +++ b/committing.rst @@ -16,7 +16,7 @@ (using Tools/scripts/reindent-rst.py) * Has the documentation been updated? * Has the test suite been updated? -* Has ``Misc/ACKS`` been updated? +* Has ``Misc/NEWS`` been updated? * Has ``Misc/ACKS`` been updated? * Has the test suite been run? -- Repository URL: http://hg.python.org/devguide From ncoghlan at gmail.com Sun Jun 19 17:18:03 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Mon, 20 Jun 2011 01:18:03 +1000 Subject: [Python-checkins] devguide: Fix copy-paste glitch :) In-Reply-To: References: Message-ID: On Mon, Jun 20, 2011 at 12:57 AM, eric.araujo wrote: > http://hg.python.org/devguide/rev/f55ad3dc4526 > changeset: ? 434:f55ad3dc4526 > user: ? ? ? ??ric Araujo > date: ? ? ? ?Sun Jun 19 16:56:58 2011 +0200 > summary: > ?Fix copy-paste glitch :) > > files: > ?committing.rst | ?2 +- > ?1 files changed, 1 insertions(+), 1 deletions(-) > > > diff --git a/committing.rst b/committing.rst > --- a/committing.rst > +++ b/committing.rst > @@ -16,7 +16,7 @@ > ? (using Tools/scripts/reindent-rst.py) > ?* Has the documentation been updated? > ?* Has the test suite been updated? > -* Has ``Misc/ACKS`` been updated? > +* Has ``Misc/NEWS`` been updated? > ?* Has ``Misc/ACKS`` been updated? > ?* Has the test suite been run? D'oh! I had it right at one point, too, but then I rearranged it and must have clobbered the wrong line in the process. Thanks for fixing it :) Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From tjreedy at udel.edu Sun Jun 19 17:52:34 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 19 Jun 2011 11:52:34 -0400 Subject: [Python-checkins] devguide: Update the committing page with various details (closes #11795, but also In-Reply-To: References: Message-ID: <4DFE1B42.7060302@udel.edu> > +* Has ``Misc/ACKS`` been updated? > +* Has ``Misc/ACKS`` been updated? Have duplicate words/lines been eliminated ;-). (I actually once used a grammar checker that caught things like the 'the the' someone else just corrected somewhere.) Aside from that, your recent changes all look helpful. > +* Has the test suite been run? > + > +Note that the automated patch check can't actually *answer* all of these > +questions, and even if it could, it still wouldn't know whether or not > +those answers were appropriate. Aside from the whitespace checks, it is just > +a memory aid to help with remembering the various elements that can go into > +making a complete patch. > + > > Commit Messages > --------------- I think this section could make clearer, as per the recent pydev discussion, that the commit message should make clear what the change is or what the new behavior is and that 'x does y' is ambiguous and insufficient. Terry From python-checkins at python.org Sun Jun 19 19:24:05 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 19:24:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_typo?= Message-ID: http://hg.python.org/cpython/rev/00f0b48eeb88 changeset: 70872:00f0b48eeb88 user: ?ric Araujo date: Sun Jun 19 18:53:31 2011 +0200 summary: Fix typo files: Lib/packaging/pypi/simple.py | 2 +- Lib/packaging/tests/pypi_server.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/packaging/pypi/simple.py b/Lib/packaging/pypi/simple.py --- a/Lib/packaging/pypi/simple.py +++ b/Lib/packaging/pypi/simple.py @@ -110,7 +110,7 @@ :param follow_externals: tell if following external links is needed or not. Default is False. :param mirrors_url: the url to look on for DNS records giving mirror - adresses. + addresses. :param mirrors: a list of mirrors (see PEP 381). :param timeout: time in seconds to consider a url has timeouted. :param mirrors_max_tries": number of times to try requesting informations diff --git a/Lib/packaging/tests/pypi_server.py b/Lib/packaging/tests/pypi_server.py --- a/Lib/packaging/tests/pypi_server.py +++ b/Lib/packaging/tests/pypi_server.py @@ -22,7 +22,7 @@ Then, the server must have only one port to rely on, eg. - >>> server.fulladress() + >>> server.fulladdress() "http://ip:port/" It could be simple to have one HTTP server, relaying the requests to the two -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 19:24:08 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 19:24:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Add_missing_documentation_f?= =?utf8?q?or_packaging=2Epypi=2Ebase_and_=2Esimple?= Message-ID: http://hg.python.org/cpython/rev/8de5fe3b1696 changeset: 70873:8de5fe3b1696 user: ?ric Araujo date: Sun Jun 19 19:23:48 2011 +0200 summary: Add missing documentation for packaging.pypi.base and .simple files: Doc/library/packaging.pypi.rst | 21 +++ Doc/library/packaging.pypi.simple.rst | 89 ++++++++++++-- 2 files changed, 96 insertions(+), 14 deletions(-) diff --git a/Doc/library/packaging.pypi.rst b/Doc/library/packaging.pypi.rst --- a/Doc/library/packaging.pypi.rst +++ b/Doc/library/packaging.pypi.rst @@ -51,3 +51,24 @@ .. method:: get_release .. method:: get_releases + + +:mod:`packaging.pypi.base` --- Base class for index crawlers +============================================================ + +.. module:: packaging.pypi.base + :synopsis: Base class used to implement crawlers. + + +.. class:: BaseClient(prefer_final, prefer_source) + + Base class containing common methods for the index crawlers or clients. One + method is currently defined: + + .. method:: download_distribution(requirements, temp_path=None, \ + prefer_source=None, prefer_final=None) + + Download a distribution from the last release according to the + requirements. If *temp_path* is provided, download to this path, + otherwise, create a temporary directory for the download. If a release is + found, the full path to the downloaded file is returned. diff --git a/Doc/library/packaging.pypi.simple.rst b/Doc/library/packaging.pypi.simple.rst --- a/Doc/library/packaging.pypi.simple.rst +++ b/Doc/library/packaging.pypi.simple.rst @@ -6,26 +6,87 @@ and distributions. -`packaging.pypi.simple` can process Python Package Indexes and provides -useful information about distributions. It also can crawl local indexes, for -instance. +The class provided by :mod:`packaging.pypi.simple` can access project indexes +and provide useful information about distributions. PyPI, other indexes and +local indexes are supported. -You should use `packaging.pypi.simple` for: - - * Search distributions by name and versions. - * Process index external pages. - * Download distributions by name and versions. - -And should not be used for: - - * Things that will end up in too long index processing (like "finding all - distributions with a specific version, no matters the name") +You should use this module to search distributions by name and versions, process +index external pages and download distributions. It is not suited for things +that will end up in too long index processing (like "finding all distributions +with a specific version, no matter the name"); use :mod:`packaging.pypi.xmlrpc` +for that. API --- -.. class:: Crawler +.. class:: Crawler(index_url=DEFAULT_SIMPLE_INDEX_URL, \ + prefer_final=False, prefer_source=True, \ + hosts=('*',), follow_externals=False, \ + mirrors_url=None, mirrors=None, timeout=15, \ + mirrors_max_tries=0, verbose=False) + + *index_url* is the address of the index to use for requests. + + The first two parameters control the query results. *prefer_final* + indicates whether a final version (not alpha, beta or candidate) is to be + prefered over a newer but non-final version (for example, whether to pick + up 1.0 over 2.0a3). It is used only for queries that don't give a version + argument. Likewise, *prefer_source* tells whether to prefer a source + distribution over a binary one, if no distribution argument was prodived. + + Other parameters are related to external links (that is links that go + outside the simple index): *hosts* is a list of hosts allowed to be + processed if *follow_externals* is true (default behavior is to follow all + hosts), *follow_externals* enables or disables following external links + (default is false, meaning disabled). + + The remaining parameters are related to the mirroring infrastructure + defined in :PEP:`381`. *mirrors_url* gives a URL to look on for DNS + records giving mirror adresses; *mirrors* is a list of mirror URLs (see + the PEP). If both *mirrors* and *mirrors_url* are given, *mirrors_url* + will only be used if *mirrors* is set to ``None``. *timeout* is the time + (in seconds) to wait before considering a URL has timed out; + *mirrors_max_tries"* is the number of times to try requesting informations + on mirrors before switching. + + The following methods are defined: + + .. method:: get_distributions(project_name, version) + + Return the distributions found in the index for the given release. + + .. method:: get_metadata(project_name, version) + + Return the metadata found on the index for this project name and + version. Currently downloads and unpacks a distribution to read the + PKG-INFO file. + + .. method:: get_release(requirements, prefer_final=None) + + Return one release that fulfills the given requirements. + + .. method:: get_releases(requirements, prefer_final=None, force_update=False) + + Search for releases and return a + :class:`~packaging.pypi.dist.ReleasesList` object containing the + results. + + .. method:: search_projects(name=None) + + Search the index for projects containing the given name and return a + list of matching names. + + See also the base class :class:`packaging.pypi.base.BaseClient` for inherited + methods. + + +.. data:: DEFAULT_SIMPLE_INDEX_URL + + The address used by default by the crawler class. It is currently + ``'http://a.pypi.python.org/simple/'``, the main PyPI installation. + + Usage Exemples -- Repository URL: http://hg.python.org/cpython From jimjjewett at gmail.com Sun Jun 19 21:40:01 2011 From: jimjjewett at gmail.com (Jim Jewett) Date: Sun, 19 Jun 2011 15:40:01 -0400 Subject: [Python-checkins] cpython: #6771: Move wrapper function into __init__ and eliminate wrapper module In-Reply-To: References: Message-ID: Does this really need to be a bare except? On Sat, Jun 18, 2011 at 8:21 PM, r.david.murray wrote: > http://hg.python.org/cpython/rev/9c96c3adbcd1 > changeset: ? 70867:9c96c3adbcd1 > user: ? ? ? ?R David Murray > date: ? ? ? ?Sat Jun 18 20:21:09 2011 -0400 > summary: > ?#6771: Move wrapper function into __init__ and eliminate wrapper module > > Andrew agreed in the issue that eliminating the module file made sense. > Wrapper has only been exposed as a function, and so there is no (easy) > way to access the wrapper module, which in any case only had the one > function in it. ?Since __init__ already contains a couple wrapper > functions, it seems to make sense to just move wrapper there instead of > importing it from a single function module. > > files: > ?Lib/curses/__init__.py | ?46 +++++++++++++++++++++++++++- > ?Lib/curses/wrapper.py ?| ?50 ------------------------------ > ?Misc/NEWS ? ? ? ? ? ? ?| ? 4 ++ > ?3 files changed, 49 insertions(+), 51 deletions(-) > > > diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py > --- a/Lib/curses/__init__.py > +++ b/Lib/curses/__init__.py > @@ -13,7 +13,6 @@ > ?__revision__ = "$Id$" > > ?from _curses import * > -from curses.wrapper import wrapper > ?import os as _os > ?import sys as _sys > > @@ -57,3 +56,48 @@ > ? ? has_key > ?except NameError: > ? ? from has_key import has_key > + > +# Wrapper for the entire curses-based application. ?Runs a function which > +# should be the rest of your curses-based application. ?If the application > +# raises an exception, wrapper() will restore the terminal to a sane state so > +# you can read the resulting traceback. > + > +def wrapper(func, *args, **kwds): > + ? ?"""Wrapper function that initializes curses and calls another function, > + ? ?restoring normal keyboard/screen behavior on error. > + ? ?The callable object 'func' is then passed the main window 'stdscr' > + ? ?as its first argument, followed by any other arguments passed to > + ? ?wrapper(). > + ? ?""" > + > + ? ?try: > + ? ? ? ?# Initialize curses > + ? ? ? ?stdscr = initscr() > + > + ? ? ? ?# Turn off echoing of keys, and enter cbreak mode, > + ? ? ? ?# where no buffering is performed on keyboard input > + ? ? ? ?noecho() > + ? ? ? ?cbreak() > + > + ? ? ? ?# In keypad mode, escape sequences for special keys > + ? ? ? ?# (like the cursor keys) will be interpreted and > + ? ? ? ?# a special value like curses.KEY_LEFT will be returned > + ? ? ? ?stdscr.keypad(1) > + > + ? ? ? ?# Start color, too. ?Harmless if the terminal doesn't have > + ? ? ? ?# color; user can test with has_color() later on. ?The try/catch > + ? ? ? ?# works around a minor bit of over-conscientiousness in the curses > + ? ? ? ?# module -- the error return from C start_color() is ignorable. > + ? ? ? ?try: > + ? ? ? ? ? ?start_color() > + ? ? ? ?except: > + ? ? ? ? ? ?pass > + > + ? ? ? ?return func(stdscr, *args, **kwds) > + ? ?finally: > + ? ? ? ?# Set everything back to normal > + ? ? ? ?if 'stdscr' in locals(): > + ? ? ? ? ? ?stdscr.keypad(0) > + ? ? ? ? ? ?echo() > + ? ? ? ? ? ?nocbreak() > + ? ? ? ? ? ?endwin() > diff --git a/Lib/curses/wrapper.py b/Lib/curses/wrapper.py > deleted file mode 100644 > --- a/Lib/curses/wrapper.py > +++ /dev/null > @@ -1,50 +0,0 @@ > -"""curses.wrapper > - > -Contains one function, wrapper(), which runs another function which > -should be the rest of your curses-based application. ?If the > -application raises an exception, wrapper() will restore the terminal > -to a sane state so you can read the resulting traceback. > - > -""" > - > -import curses > - > -def wrapper(func, *args, **kwds): > - ? ?"""Wrapper function that initializes curses and calls another function, > - ? ?restoring normal keyboard/screen behavior on error. > - ? ?The callable object 'func' is then passed the main window 'stdscr' > - ? ?as its first argument, followed by any other arguments passed to > - ? ?wrapper(). > - ? ?""" > - > - ? ?try: > - ? ? ? ?# Initialize curses > - ? ? ? ?stdscr = curses.initscr() > - > - ? ? ? ?# Turn off echoing of keys, and enter cbreak mode, > - ? ? ? ?# where no buffering is performed on keyboard input > - ? ? ? ?curses.noecho() > - ? ? ? ?curses.cbreak() > - > - ? ? ? ?# In keypad mode, escape sequences for special keys > - ? ? ? ?# (like the cursor keys) will be interpreted and > - ? ? ? ?# a special value like curses.KEY_LEFT will be returned > - ? ? ? ?stdscr.keypad(1) > - > - ? ? ? ?# Start color, too. ?Harmless if the terminal doesn't have > - ? ? ? ?# color; user can test with has_color() later on. ?The try/catch > - ? ? ? ?# works around a minor bit of over-conscientiousness in the curses > - ? ? ? ?# module -- the error return from C start_color() is ignorable. > - ? ? ? ?try: > - ? ? ? ? ? ?curses.start_color() > - ? ? ? ?except: > - ? ? ? ? ? ?pass > - > - ? ? ? ?return func(stdscr, *args, **kwds) > - ? ?finally: > - ? ? ? ?# Set everything back to normal > - ? ? ? ?if 'stdscr' in locals(): > - ? ? ? ? ? ?stdscr.keypad(0) > - ? ? ? ? ? ?curses.echo() > - ? ? ? ? ? ?curses.nocbreak() > - ? ? ? ? ? ?curses.endwin() > diff --git a/Misc/NEWS b/Misc/NEWS > --- a/Misc/NEWS > +++ b/Misc/NEWS > @@ -193,6 +193,10 @@ > ?Library > ?------- > > +- Issue #6771: moved the curses.wrapper function from the single-function > + ?wrapper module into __init__, eliminating the module. ?Since __init__ was > + ?already importing the function to curses.wrapper, there is no API change. > + > ?- Issue #11584: email.header.decode_header no longer fails if the header > ? passed to it is a Header object, and Header/make_header no longer fail > ? if given binary unknown-8bit input. > > -- > Repository URL: http://hg.python.org/cpython > > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > http://mail.python.org/mailman/listinfo/python-checkins > > From python-checkins at python.org Sun Jun 19 21:47:21 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 21:47:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_packaging=3A_Add_the_projec?= =?utf8?q?t_directory_to_sys=2Epath_to_support_local_setup_hooks=2E?= Message-ID: http://hg.python.org/cpython/rev/b732b02bd0ba changeset: 70874:b732b02bd0ba user: ?ric Araujo date: Sun Jun 19 21:23:43 2011 +0200 summary: packaging: Add the project directory to sys.path to support local setup hooks. Original patch by Vinay Sajip on #11637. files: Lib/packaging/config.py | 23 ++++++++++------- Lib/packaging/tests/test_config.py | 22 ++++++++++++++++- Misc/NEWS | 5 +++- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/Lib/packaging/config.py b/Lib/packaging/config.py --- a/Lib/packaging/config.py +++ b/Lib/packaging/config.py @@ -134,15 +134,20 @@ if 'setup_hooks' in content['global']: setup_hooks = split_multiline(content['global']['setup_hooks']) - for line in setup_hooks: - try: - hook = resolve_name(line) - except ImportError as e: - logger.warning('cannot find setup hook: %s', e.args[0]) - else: - self.setup_hooks.append(hook) - - self.run_hooks(content) + # add project directory to sys.path, to allow hooks to be + # distributed with the project + sys.path.insert(0, cfg_directory) + try: + for line in setup_hooks: + try: + hook = resolve_name(line) + except ImportError as e: + logger.warning('cannot find setup hook: %s', e.args[0]) + else: + self.setup_hooks.append(hook) + self.run_hooks(content) + finally: + sys.path.pop(0) metadata = self.dist.metadata diff --git a/Lib/packaging/tests/test_config.py b/Lib/packaging/tests/test_config.py --- a/Lib/packaging/tests/test_config.py +++ b/Lib/packaging/tests/test_config.py @@ -126,6 +126,15 @@ """ +HOOKS_MODULE = """ +import logging + +logger = logging.getLogger('packaging') + +def logging_hook(config): + logger.warning('logging_hook called') +""" + class DCompiler: name = 'd' @@ -326,10 +335,21 @@ self.assertEqual(ext.extra_compile_args, cargs) self.assertEqual(ext.language, 'cxx') + def test_project_setup_hook_works(self): + # Bug #11637: ensure the project directory is on sys.path to allow + # project-specific hooks + self.write_setup({'setup-hooks': 'hooks.logging_hook'}) + self.write_file('README', 'yeah') + self.write_file('hooks.py', HOOKS_MODULE) + self.get_dist() + logs = self.get_logs(logging.WARNING) + self.assertEqual(['logging_hook called'], logs) + self.assertIn('hooks', sys.modules) + def test_missing_setup_hook_warns(self): self.write_setup({'setup-hooks': 'this.does._not.exist'}) self.write_file('README', 'yeah') - dist = self.get_dist() + self.get_dist() logs = self.get_logs(logging.WARNING) self.assertEqual(1, len(logs)) self.assertIn('cannot find setup hook', logs[0]) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -193,7 +193,10 @@ Library ------- -- Issue #6771: moved the curses.wrapper function from the single-function +- Issue #11637: Fix support for importing packaging setup hooks from the + project directory. + +- Issue #6771: Moved the curses.wrapper function from the single-function wrapper module into __init__, eliminating the module. Since __init__ was already importing the function to curses.wrapper, there is no API change. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 21:47:21 2011 From: python-checkins at python.org (eric.araujo) Date: Sun, 19 Jun 2011 21:47:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Improve_documentation_of_pa?= =?utf8?q?ckaging_hooks?= Message-ID: http://hg.python.org/cpython/rev/7d3fbce32e07 changeset: 70875:7d3fbce32e07 user: ?ric Araujo date: Sun Jun 19 21:34:16 2011 +0200 summary: Improve documentation of packaging hooks files: Doc/packaging/commandhooks.rst | 49 +++++++++++++-------- Doc/packaging/setupcfg.rst | 9 ++- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Doc/packaging/commandhooks.rst b/Doc/packaging/commandhooks.rst --- a/Doc/packaging/commandhooks.rst +++ b/Doc/packaging/commandhooks.rst @@ -1,36 +1,47 @@ .. TODO integrate this in commandref and configfile +.. _packaging-command-hooks: + ============= Command hooks ============= Packaging provides a way of extending its commands by the use of pre- and -post- command hooks. The hooks are simple Python functions (or any callable -objects) and are specified in the config file using their full qualified names. -The pre-hooks are run after the command is finalized (its options are -processed), but before it is run. The post-hooks are run after the command -itself. Both types of hooks receive an instance of the command object. +post-command hooks. Hooks are Python functions (or any callable object) that +take a command object as argument. They're specified in :ref:`config files +` using their fully qualified names. After a +command is finalized (its options are processed), the pre-command hooks are +executed, then the command itself is run, and finally the post-command hooks are +executed. See also global setup hooks in :ref:`setupcfg-spec`. -Sample usage of hooks -===================== +.. _packaging-finding-hooks: -Firstly, you need to make sure your hook is present in the path. This is usually -done by dropping them to the same folder where `setup.py` file lives :: +Finding hooks +============= - # file: myhooks.py - def my_install_hook(install_cmd): - print "Oh la la! Someone is installing my project!" +As a hook is configured with a Python dotted name, it must either be defined in +a module installed on the system, or in a module present in the project +directory, where the :file:`setup.cfg` file lives:: -Then, you need to point to it in your `setup.cfg` file, under the appropriate -command section :: + # file: _setuphooks.py + + def hook(install_cmd): + metadata = install_cmd.dist.metadata + print('Hooked while installing %r %s!' % (metadata['Name'], + metadata['Version'])) + +Then you need to configure it in :file:`setup.cfg`:: [install_dist] - pre-hook.project = myhooks.my_install_hook + pre-hook.a = _setuphooks.hook -The hooks defined in different config files (system-wide, user-wide and -package-wide) do not override each other as long as they are specified with -different aliases (additional names after the dot). The alias in the example -above is ``project``. +Packaging will add the project directory to :data:`sys.path` and find the +``_setuphooks`` module. + +Hooks defined in different config files (system-wide, user-wide and +project-wide) do not override each other as long as they are specified with +different aliases (additional names after the dot). The alias in the example +above is ``a``. diff --git a/Doc/packaging/setupcfg.rst b/Doc/packaging/setupcfg.rst --- a/Doc/packaging/setupcfg.rst +++ b/Doc/packaging/setupcfg.rst @@ -178,17 +178,20 @@ setup_hooks Defines a list of callables to be called right after the :file:`setup.cfg` - file is read, before any other processing. The callables are executed in the + file is read, before any other processing. Each value is a Python dotted + name to an object, which has to be defined in a module present in the project + directory alonside :file:`setup.cfg` or on Python's :data:`sys.path` (see + :ref:`packaging-finding-hooks`). The callables are executed in the order they're found in the file; if one of them cannot be found, tools should not stop, but for example produce a warning and continue with the next line. Each callable receives the configuration as a dictionary (keys are :file:`setup.cfg` sections, values are dictionaries of fields) and can make - any changes to it. *optional*, *multi* + any change to it. *optional*, *multi* Example:: [global] - setup_hooks = package.setup.customize_dist + setup_hooks = _setuphooks.customize_config Metadata -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 22:05:19 2011 From: python-checkins at python.org (martin.v.loewis) Date: Sun, 19 Jun 2011 22:05:19 +0200 (CEST) Subject: [Python-checkins] r88855 - tracker/instances/python-dev/detectors/hgrepo.py Message-ID: <3Qy5sC10WjzM68@mail.python.org> Author: martin.v.loewis Date: Sun Jun 19 22:05:18 2011 New Revision: 88855 Log: Issue 405: Support repo#branch syntax for adding hg repos. Added: tracker/instances/python-dev/detectors/hgrepo.py (contents, props changed) Added: tracker/instances/python-dev/detectors/hgrepo.py ============================================================================== --- (empty file) +++ tracker/instances/python-dev/detectors/hgrepo.py Sun Jun 19 22:05:18 2011 @@ -0,0 +1,12 @@ +# Auditor for hgrepo records +# Split repo#branch URLs in repo and branch + +def hgsplit(db, cl, nodeid, newvalues): + url = newvalues.get('url','') + if '#' in url: + url, branch = url.split('#', 1) + newvalues['url'] = url + newvalues['patchbranch'] = branch + +def init(db): + db.hgrepo.audit('create', hgsplit) From python-checkins at python.org Sun Jun 19 22:57:11 2011 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 19 Jun 2011 22:57:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_Fix_closes_issu?= =?utf8?q?e12261_-_Minor_documention_changes_in_the_urllib=2Eparse=2Erst?= Message-ID: http://hg.python.org/cpython/rev/4211ace1ff5d changeset: 70876:4211ace1ff5d branch: 3.1 parent: 70784:6f0bcfc17a9e user: Senthil Kumaran date: Sun Jun 19 13:52:49 2011 -0700 summary: Fix closes issue12261 - Minor documention changes in the urllib.parse.rst files: Doc/library/urllib.parse.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -53,7 +53,7 @@ input is presumed to be a relative URL and thus to start with a path component. - >>> from urlparse import urlparse + >>> from urllib.parse import urlparse >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') @@ -351,7 +351,7 @@ .. seealso:: :rfc:`3986` - Uniform Resource Identifiers - This is the current standard (STD66). Any changes to urlparse module + This is the current standard (STD66). Any changes to urllib.parse module should conform to this. Certain deviations could be observed, which are mostly for backward compatibility purposes and for certain de-facto parsing requirements as commonly observed in major browsers. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 22:57:11 2011 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 19 Jun 2011 22:57:11 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_from_3=2E1_for_issue_issue12261=2E?= Message-ID: http://hg.python.org/cpython/rev/18f3239b3d48 changeset: 70877:18f3239b3d48 branch: 3.2 parent: 70865:f9b4cfc19264 parent: 70876:4211ace1ff5d user: Senthil Kumaran date: Sun Jun 19 13:55:48 2011 -0700 summary: merge from 3.1 for issue issue12261. files: Doc/library/urllib.parse.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -61,7 +61,7 @@ input is presumed to be a relative URL and thus to start with a path component. - >>> from urlparse import urlparse + >>> from urllib.parse import urlparse >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') @@ -537,7 +537,7 @@ .. seealso:: :rfc:`3986` - Uniform Resource Identifiers - This is the current standard (STD66). Any changes to urlparse module + This is the current standard (STD66). Any changes to urllib.parse module should conform to this. Certain deviations could be observed, which are mostly for backward compatibility purposes and for certain de-facto parsing requirements as commonly observed in major browsers. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 19 22:57:12 2011 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 19 Jun 2011 22:57:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/b061265bb0e0 changeset: 70878:b061265bb0e0 parent: 70875:7d3fbce32e07 parent: 70877:18f3239b3d48 user: Senthil Kumaran date: Sun Jun 19 13:56:56 2011 -0700 summary: merge from 3.2 files: Doc/library/urllib.parse.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -61,7 +61,7 @@ input is presumed to be a relative URL and thus to start with a path component. - >>> from urlparse import urlparse + >>> from urllib.parse import urlparse >>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html') ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') @@ -537,7 +537,7 @@ .. seealso:: :rfc:`3986` - Uniform Resource Identifiers - This is the current standard (STD66). Any changes to urlparse module + This is the current standard (STD66). Any changes to urllib.parse module should conform to this. Certain deviations could be observed, which are mostly for backward compatibility purposes and for certain de-facto parsing requirements as commonly observed in major browsers. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 00:13:54 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 00:13:54 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_duplicate_-I?= Message-ID: http://hg.python.org/cpython/rev/0d0ca6f95d9d changeset: 70879:0d0ca6f95d9d user: Benjamin Peterson date: Sun Jun 19 17:17:30 2011 -0500 summary: remove duplicate -I files: Makefile.pre.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -73,7 +73,7 @@ # Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to # be able to build extension modules using the directories specified in the # environment variables -PY_CPPFLAGS= -I. -IInclude -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) +PY_CPPFLAGS= -I. -IInclude $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) NO_AS_NEEDED= @NO_AS_NEEDED@ LDLAST= @LDLAST@ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 00:45:45 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 00:45:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_fix_uglyNamingC?= =?utf8?q?onvention?= Message-ID: http://hg.python.org/cpython/rev/9e58a638f028 changeset: 70880:9e58a638f028 branch: 3.2 parent: 70877:18f3239b3d48 user: Benjamin Peterson date: Sun Jun 19 17:49:13 2011 -0500 summary: fix uglyNamingConvention files: Lib/test/test_super.py | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -44,33 +44,33 @@ class TestSuper(unittest.TestCase): - def testBasicsWorking(self): + def test_basics_working(self): self.assertEqual(D().f(), 'ABCD') - def testClassGetattrWorking(self): + def test_class_getattr_working(self): self.assertEqual(D.f(D()), 'ABCD') - def testSubclassNoOverrideWorking(self): + def test_subclass_no_override_working(self): self.assertEqual(E().f(), 'ABCD') self.assertEqual(E.f(E()), 'ABCD') - def testUnboundMethodTransferWorking(self): + def test_unbound_method_transfer_working(self): self.assertEqual(F().f(), 'ABCD') self.assertEqual(F.f(F()), 'ABCD') - def testClassMethodsStillWorking(self): + def test_class_methods_still_working(self): self.assertEqual(A.cm(), (A, 'A')) self.assertEqual(A().cm(), (A, 'A')) self.assertEqual(G.cm(), (G, 'A')) self.assertEqual(G().cm(), (G, 'A')) - def testSuperInClassMethodsWorking(self): + def test_super_in_class_methods_working(self): d = D() self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D')) e = E() self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D')) - def testSuperWithClosure(self): + def test_super_with_closure(self): # Issue4360: super() did not work in a function that # contains a closure class E(A): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 00:45:46 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 00:45:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/5dd75cdd445a changeset: 70881:5dd75cdd445a parent: 70879:0d0ca6f95d9d parent: 70880:9e58a638f028 user: Benjamin Peterson date: Sun Jun 19 17:49:22 2011 -0500 summary: merge 3.2 files: Lib/test/test_super.py | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -44,33 +44,33 @@ class TestSuper(unittest.TestCase): - def testBasicsWorking(self): + def test_basics_working(self): self.assertEqual(D().f(), 'ABCD') - def testClassGetattrWorking(self): + def test_class_getattr_working(self): self.assertEqual(D.f(D()), 'ABCD') - def testSubclassNoOverrideWorking(self): + def test_subclass_no_override_working(self): self.assertEqual(E().f(), 'ABCD') self.assertEqual(E.f(E()), 'ABCD') - def testUnboundMethodTransferWorking(self): + def test_unbound_method_transfer_working(self): self.assertEqual(F().f(), 'ABCD') self.assertEqual(F.f(F()), 'ABCD') - def testClassMethodsStillWorking(self): + def test_class_methods_still_working(self): self.assertEqual(A.cm(), (A, 'A')) self.assertEqual(A().cm(), (A, 'A')) self.assertEqual(G.cm(), (G, 'A')) self.assertEqual(G().cm(), (G, 'A')) - def testSuperInClassMethodsWorking(self): + def test_super_in_class_methods_working(self): d = D() self.assertEqual(d.cm(), (d, (D, (D, (D, 'A'), 'B'), 'C'), 'D')) e = E() self.assertEqual(e.cm(), (e, (E, (E, (E, 'A'), 'B'), 'C'), 'D')) - def testSuperWithClosure(self): + def test_super_with_closure(self): # Issue4360: super() did not work in a function that # contains a closure class E(A): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:00:44 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:00:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_Issu?= =?utf8?q?e12315_-_Updates_to_http=2Eclient_documentation=2E?= Message-ID: http://hg.python.org/cpython/rev/d801b570b1dd changeset: 70882:d801b570b1dd branch: 3.2 parent: 70880:9e58a638f028 user: Senthil Kumaran date: Sun Jun 19 16:56:49 2011 -0700 summary: Fix closes Issue12315 - Updates to http.client documentation. files: Doc/library/http.client.rst | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -543,6 +543,9 @@ A debugging hook. If :attr:`debuglevel` is greater than zero, messages will be printed to stdout as the response is read and parsed. +.. attribute:: HTTPResponse.closed + + Is True if the stream is closed. Examples -------- @@ -555,7 +558,15 @@ >>> r1 = conn.getresponse() >>> print(r1.status, r1.reason) 200 OK - >>> data1 = r1.read() + >>> data1 = r1.read() # This will return entire content. + >>> # The following example demonstrates reading data in chunks. + >>> conn.request("GET", "/index.html") + >>> r1 = conn.getresponse() + >>> while not r1.closed: + ... print(r1.read(200)) # 200 bytes + b'>> # Example of an invalid request >>> conn.request("GET", "/parrot.spam") >>> r2 = conn.getresponse() >>> print(r2.status, r2.reason) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:00:44 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:00:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2=2E_Updates_to_http=2Eclient_documentation?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/f3e27bb31adf changeset: 70883:f3e27bb31adf parent: 70881:5dd75cdd445a parent: 70882:d801b570b1dd user: Senthil Kumaran date: Sun Jun 19 16:57:49 2011 -0700 summary: merge from 3.2. Updates to http.client documentation. files: Doc/library/http.client.rst | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -543,6 +543,9 @@ A debugging hook. If :attr:`debuglevel` is greater than zero, messages will be printed to stdout as the response is read and parsed. +.. attribute:: HTTPResponse.closed + + Is True if the stream is closed. Examples -------- @@ -555,7 +558,15 @@ >>> r1 = conn.getresponse() >>> print(r1.status, r1.reason) 200 OK - >>> data1 = r1.read() + >>> data1 = r1.read() # This will return entire content. + >>> # The following example demonstrates reading data in chunks. + >>> conn.request("GET", "/index.html") + >>> r1 = conn.getresponse() + >>> while not r1.closed: + ... print(r1.read(200)) # 200 bytes + b'>> # Example of an invalid request >>> conn.request("GET", "/parrot.spam") >>> r2 = conn.getresponse() >>> print(r2.status, r2.reason) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:00:45 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:00:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Whitespace_nit_?= =?utf8?q?fixed_using_reident=2E?= Message-ID: http://hg.python.org/cpython/rev/4444afcfb22e changeset: 70884:4444afcfb22e branch: 3.2 parent: 70882:d801b570b1dd user: Senthil Kumaran date: Sun Jun 19 16:59:41 2011 -0700 summary: Whitespace nit fixed using reident. files: Doc/library/http.client.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -545,7 +545,7 @@ .. attribute:: HTTPResponse.closed - Is True if the stream is closed. + Is True if the stream is closed. Examples -------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:00:46 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:00:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/c9bc72398a0e changeset: 70885:c9bc72398a0e parent: 70883:f3e27bb31adf parent: 70884:4444afcfb22e user: Senthil Kumaran date: Sun Jun 19 17:00:29 2011 -0700 summary: merge from 3.2 files: Doc/library/http.client.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -545,7 +545,7 @@ .. attribute:: HTTPResponse.closed - Is True if the stream is closed. + Is True if the stream is closed. Examples -------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:42:34 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:42:34 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_Issu?= =?utf8?q?e12359_-_Minor_update_to_module_import_description=2E?= Message-ID: http://hg.python.org/cpython/rev/bf8b4c43fb94 changeset: 70886:bf8b4c43fb94 branch: 3.2 parent: 70884:4444afcfb22e user: Senthil Kumaran date: Sun Jun 19 17:37:06 2011 -0700 summary: Fix closes Issue12359 - Minor update to module import description. files: Doc/tutorial/modules.rst | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -159,13 +159,14 @@ .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter searches for a file -named :file:`spam.py` in the current directory, and then in the list of -directories specified by the environment variable :envvar:`PYTHONPATH`. This -has the same syntax as the shell variable :envvar:`PATH`, that is, a list of -directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not -found there, the search continues in an installation-dependent default path; on -Unix, this is usually :file:`.:/usr/local/lib/python`. +When a module named :mod:`spam` is imported, the interpreter searches for a +file named :file:`spam.py` in the directory containing the input script (or +thecurrent directory), and then in the list of directories specified by the +environment variable :envvar:`PYTHONPATH`. This has the same syntax as the +shell variable :envvar:`PATH`, that is, a list of directory names. When +:envvar:`PYTHONPATH` is not set, or when the file is not found there, the +search continues in an installation-dependent default path; on Unix, this is +usually :file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:42:35 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:42:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2=2E_Issue_12359?= Message-ID: http://hg.python.org/cpython/rev/8754fd2ff64a changeset: 70887:8754fd2ff64a parent: 70885:c9bc72398a0e parent: 70886:bf8b4c43fb94 user: Senthil Kumaran date: Sun Jun 19 17:41:01 2011 -0700 summary: merge from 3.2. Issue 12359 files: Doc/tutorial/modules.rst | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -159,13 +159,14 @@ .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter searches for a file -named :file:`spam.py` in the current directory, and then in the list of -directories specified by the environment variable :envvar:`PYTHONPATH`. This -has the same syntax as the shell variable :envvar:`PATH`, that is, a list of -directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not -found there, the search continues in an installation-dependent default path; on -Unix, this is usually :file:`.:/usr/local/lib/python`. +When a module named :mod:`spam` is imported, the interpreter searches for a +file named :file:`spam.py` in the directory containing the input script (or +the current directory), and then in the list of directories specified by the +environment variable :envvar:`PYTHONPATH`. This has the same syntax as the +shell variable :envvar:`PATH`, that is, a list of directory names. When +:envvar:`PYTHONPATH` is not set, or when the file is not found there, the +search continues in an installation-dependent default path; on Unix, this is +usually :file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:42:36 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:42:36 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_minor_space_nit?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/0cc554b104c1 changeset: 70888:0cc554b104c1 branch: 3.2 parent: 70886:bf8b4c43fb94 user: Senthil Kumaran date: Sun Jun 19 17:41:33 2011 -0700 summary: minor space nit. files: Doc/tutorial/modules.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -161,7 +161,7 @@ When a module named :mod:`spam` is imported, the interpreter searches for a file named :file:`spam.py` in the directory containing the input script (or -thecurrent directory), and then in the list of directories specified by the +the current directory), and then in the list of directories specified by the environment variable :envvar:`PYTHONPATH`. This has the same syntax as the shell variable :envvar:`PATH`, that is, a list of directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not found there, the -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:45:01 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 02:45:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_use_a_invalid_name_for_the_?= =?utf8?b?X19jbGFzc19fIGNsb3N1cmUgZm9yIHN1cGVyKCkgKGNsb3NlcyAjMTIzNzAp?= Message-ID: http://hg.python.org/cpython/rev/2d62ee4e7d98 changeset: 70889:2d62ee4e7d98 parent: 70881:5dd75cdd445a user: Benjamin Peterson date: Sun Jun 19 19:42:22 2011 -0500 summary: use a invalid name for the __class__ closure for super() (closes #12370) This prevents the assignment of __class__ in the class body from breaking super. (Although a determined person could do locals()["@__class__"] = 4) files: Lib/test/test_super.py | 10 ++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 2 +- Python/compile.c | 2 +- Python/symtable.c | 19 +++++++++++-------- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -81,6 +81,16 @@ self.assertEqual(E().f(), 'AE') + def test___class___set(self): + # See issue #12370 + class X(A): + def f(self): + return super().f() + __class__ = 413 + x = X() + self.assertEqual(x.f(), 'A') + self.assertEqual(x.__class__, 413) + def test_main(): support.run_unittest(TestSuper) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12370: Fix super with not arguments when __class__ is overriden in the + class body. + - Issue #12084: os.stat on Windows now works properly with relative symbolic links when called from any directory. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6399,7 +6399,7 @@ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); assert(PyUnicode_Check(name)); if (!PyUnicode_CompareWithASCIIString(name, - "__class__")) { + "@__class__")) { Py_ssize_t index = co->co_nlocals + PyTuple_GET_SIZE(co->co_cellvars) + i; PyObject *cell = f->f_localsplus[index]; diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -1566,7 +1566,7 @@ return 0; } /* return the (empty) __class__ cell */ - str = PyUnicode_InternFromString("__class__"); + str = PyUnicode_InternFromString("@__class__"); if (str == NULL) { compiler_exit_scope(c); return 0; diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -225,10 +225,17 @@ struct symtable * PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) { - struct symtable *st = symtable_new(); + struct symtable *st; asdl_seq *seq; int i; + if (__class__ == NULL) { + __class__ = PyUnicode_InternFromString("@__class__"); + if (__class__ == NULL) + return NULL; + } + + st = symtable_new(); if (st == NULL) return st; st->st_filename = filename; @@ -744,8 +751,6 @@ } else { /* Special-case __class__ */ - if (!GET_IDENTIFIER(__class__)) - goto error; assert(PySet_Contains(local, __class__) == 1); if (PySet_Add(newbound, __class__) < 0) goto error; @@ -783,7 +788,7 @@ NULL)) goto error; else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree, - "__class__")) + "@__class__")) goto error; /* Records the results of the analysis in the symbol table entry */ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, @@ -1143,8 +1148,7 @@ if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, s->lineno, s->col_offset)) return 0; - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, DEF_LOCAL) || + if (!symtable_add_def(st, __class__, DEF_LOCAL) || !GET_IDENTIFIER(__locals__) || !symtable_add_def(st, __locals__, DEF_PARAM)) { symtable_exit_block(st, s); @@ -1417,8 +1421,7 @@ if (e->v.Name.ctx == Load && st->st_cur->ste_type == FunctionBlock && !PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) { - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE)) + if (!symtable_add_def(st, __class__, USE)) return 0; } break; -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:45:02 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 02:45:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/8bf6da2287a8 changeset: 70890:8bf6da2287a8 parent: 70889:2d62ee4e7d98 parent: 70887:8754fd2ff64a user: Benjamin Peterson date: Sun Jun 19 19:48:38 2011 -0500 summary: merge heads files: Doc/library/http.client.rst | 13 ++++++++++++- Doc/tutorial/modules.rst | 15 ++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -543,6 +543,9 @@ A debugging hook. If :attr:`debuglevel` is greater than zero, messages will be printed to stdout as the response is read and parsed. +.. attribute:: HTTPResponse.closed + + Is True if the stream is closed. Examples -------- @@ -555,7 +558,15 @@ >>> r1 = conn.getresponse() >>> print(r1.status, r1.reason) 200 OK - >>> data1 = r1.read() + >>> data1 = r1.read() # This will return entire content. + >>> # The following example demonstrates reading data in chunks. + >>> conn.request("GET", "/index.html") + >>> r1 = conn.getresponse() + >>> while not r1.closed: + ... print(r1.read(200)) # 200 bytes + b'>> # Example of an invalid request >>> conn.request("GET", "/parrot.spam") >>> r2 = conn.getresponse() >>> print(r2.status, r2.reason) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -159,13 +159,14 @@ .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter searches for a file -named :file:`spam.py` in the current directory, and then in the list of -directories specified by the environment variable :envvar:`PYTHONPATH`. This -has the same syntax as the shell variable :envvar:`PATH`, that is, a list of -directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not -found there, the search continues in an installation-dependent default path; on -Unix, this is usually :file:`.:/usr/local/lib/python`. +When a module named :mod:`spam` is imported, the interpreter searches for a +file named :file:`spam.py` in the directory containing the input script (or +the current directory), and then in the list of directories specified by the +environment variable :envvar:`PYTHONPATH`. This has the same syntax as the +shell variable :envvar:`PATH`, that is, a list of directory names. When +:envvar:`PYTHONPATH` is not set, or when the file is not found there, the +search continues in an installation-dependent default path; on Unix, this is +usually :file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:46:20 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:46:20 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_issue12359?= =?utf8?q?=2E_Minor_doc_update_on_import_module_description=2E?= Message-ID: http://hg.python.org/cpython/rev/6c16a31e0442 changeset: 70891:6c16a31e0442 branch: 2.7 parent: 70864:dc78ab3f7bc5 user: Senthil Kumaran date: Sun Jun 19 17:45:36 2011 -0700 summary: Fix issue12359. Minor doc update on import module description. files: Doc/tutorial/modules.rst | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -155,13 +155,14 @@ .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter searches for a file -named :file:`spam.py` in the current directory, and then in the list of -directories specified by the environment variable :envvar:`PYTHONPATH`. This -has the same syntax as the shell variable :envvar:`PATH`, that is, a list of -directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not -found there, the search continues in an installation-dependent default path; on -Unix, this is usually :file:`.:/usr/local/lib/python`. +When a module named :mod:`spam` is imported, the interpreter searches for a +file named :file:`spam.py` in the directory containing the input script (or the +current directory), and then in the list of directories specified by the +environment variable :envvar:`PYTHONPATH`. This has the same syntax as the +shell variable :envvar:`PATH`, that is, a list of directory names. When +:envvar:`PYTHONPATH` is not set, or when the file is not found there, the +search continues in an installation-dependent default path; on Unix, this is +usually :file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:51:01 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:51:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_outstanding_merge_with_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/4a826733cc39 changeset: 70892:4a826733cc39 parent: 70887:8754fd2ff64a parent: 70888:0cc554b104c1 user: Senthil Kumaran date: Sun Jun 19 17:48:35 2011 -0700 summary: outstanding merge with 3.2 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:51:02 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 02:51:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/631b20cca746 changeset: 70893:631b20cca746 parent: 70892:4a826733cc39 parent: 70890:8bf6da2287a8 user: Senthil Kumaran date: Sun Jun 19 17:50:53 2011 -0700 summary: merge heads files: Lib/test/test_super.py | 10 ++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 2 +- Python/compile.c | 2 +- Python/symtable.c | 19 +++++++++++-------- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -81,6 +81,16 @@ self.assertEqual(E().f(), 'AE') + def test___class___set(self): + # See issue #12370 + class X(A): + def f(self): + return super().f() + __class__ = 413 + x = X() + self.assertEqual(x.f(), 'A') + self.assertEqual(x.__class__, 413) + def test_main(): support.run_unittest(TestSuper) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #12370: Fix super with not arguments when __class__ is overriden in the + class body. + - Issue #12084: os.stat on Windows now works properly with relative symbolic links when called from any directory. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6399,7 +6399,7 @@ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); assert(PyUnicode_Check(name)); if (!PyUnicode_CompareWithASCIIString(name, - "__class__")) { + "@__class__")) { Py_ssize_t index = co->co_nlocals + PyTuple_GET_SIZE(co->co_cellvars) + i; PyObject *cell = f->f_localsplus[index]; diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -1566,7 +1566,7 @@ return 0; } /* return the (empty) __class__ cell */ - str = PyUnicode_InternFromString("__class__"); + str = PyUnicode_InternFromString("@__class__"); if (str == NULL) { compiler_exit_scope(c); return 0; diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -225,10 +225,17 @@ struct symtable * PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future) { - struct symtable *st = symtable_new(); + struct symtable *st; asdl_seq *seq; int i; + if (__class__ == NULL) { + __class__ = PyUnicode_InternFromString("@__class__"); + if (__class__ == NULL) + return NULL; + } + + st = symtable_new(); if (st == NULL) return st; st->st_filename = filename; @@ -744,8 +751,6 @@ } else { /* Special-case __class__ */ - if (!GET_IDENTIFIER(__class__)) - goto error; assert(PySet_Contains(local, __class__) == 1); if (PySet_Add(newbound, __class__) < 0) goto error; @@ -783,7 +788,7 @@ NULL)) goto error; else if (ste->ste_type == ClassBlock && !analyze_cells(scopes, newfree, - "__class__")) + "@__class__")) goto error; /* Records the results of the analysis in the symbol table entry */ if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, @@ -1143,8 +1148,7 @@ if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, s->lineno, s->col_offset)) return 0; - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, DEF_LOCAL) || + if (!symtable_add_def(st, __class__, DEF_LOCAL) || !GET_IDENTIFIER(__locals__) || !symtable_add_def(st, __locals__, DEF_PARAM)) { symtable_exit_block(st, s); @@ -1417,8 +1421,7 @@ if (e->v.Name.ctx == Load && st->st_cur->ste_type == FunctionBlock && !PyUnicode_CompareWithASCIIString(e->v.Name.id, "super")) { - if (!GET_IDENTIFIER(__class__) || - !symtable_add_def(st, __class__, USE)) + if (!symtable_add_def(st, __class__, USE)) return 0; } break; -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:51:42 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 02:51:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_bump_magic_for_super_closur?= =?utf8?q?e_change?= Message-ID: http://hg.python.org/cpython/rev/9a6d9ac6fb2e changeset: 70894:9a6d9ac6fb2e parent: 70890:8bf6da2287a8 user: Benjamin Peterson date: Sun Jun 19 19:54:45 2011 -0500 summary: bump magic for super closure change files: Python/import.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -102,6 +102,7 @@ Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR) tag: cpython-32 Python 3.2a2 3180 (add DELETE_DEREF) + Python 3.3a0 3190 __class__ super closure changed */ /* MAGIC must change whenever the bytecode emitted by the compiler may no @@ -114,7 +115,7 @@ #define STRIFY(name) QUOTE(name) #define MAJOR STRIFY(PY_MAJOR_VERSION) #define MINOR STRIFY(PY_MINOR_VERSION) -#define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (3190 | ((long)'\r'<<16) | ((long)'\n'<<24)) #define TAG "cpython-" MAJOR MINOR; #define CACHEDIR "__pycache__" static const Py_UNICODE CACHEDIR_UNICODE[] = { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 02:51:42 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 20 Jun 2011 02:51:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/2d5de8f19957 changeset: 70895:2d5de8f19957 parent: 70894:9a6d9ac6fb2e parent: 70893:631b20cca746 user: Benjamin Peterson date: Sun Jun 19 19:55:19 2011 -0500 summary: merge heads files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 03:25:38 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 03:25:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_issu?= =?utf8?q?e_12360_-__correcting_parameter_names_in_asyncore_documentation?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/d310cc1c3a5d changeset: 70896:d310cc1c3a5d branch: 3.2 parent: 70888:0cc554b104c1 user: Senthil Kumaran date: Sun Jun 19 18:22:33 2011 -0700 summary: Fix closes issue 12360 - correcting parameter names in asyncore documentation. files: Doc/library/asyncore.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -157,8 +157,8 @@ Called on listening channels (passive openers) when a connection has been established with a new remote endpoint that has issued a :meth:`connect` - call for the local endpoint. *conn* is a *new* socket object usable to - send and receive data on the connection, and *address* is the address + call for the local endpoint. *sock* is a *new* socket object usable to + send and receive data on the connection, and *addr* is the address bound to the socket on the other end of the connection. .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 03:25:39 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 03:25:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/618b681660e0 changeset: 70897:618b681660e0 parent: 70895:2d5de8f19957 parent: 70896:d310cc1c3a5d user: Senthil Kumaran date: Sun Jun 19 18:23:17 2011 -0700 summary: merge from 3.2 files: Doc/library/asyncore.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -157,8 +157,8 @@ Called on listening channels (passive openers) when a connection has been established with a new remote endpoint that has issued a :meth:`connect` - call for the local endpoint. *conn* is a *new* socket object usable to - send and receive data on the connection, and *address* is the address + call for the local endpoint. *sock* is a *new* socket object usable to + send and receive data on the connection, and *addr* is the address bound to the socket on the other end of the connection. .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From rdmurray at bitdance.com Mon Jun 20 04:39:32 2011 From: rdmurray at bitdance.com (R. David Murray) Date: Sun, 19 Jun 2011 22:39:32 -0400 Subject: [Python-checkins] [Python-Dev] cpython: #6771: Move wrapper function into __init__ and eliminate wrapper module In-Reply-To: References: Message-ID: <20110620023933.0ABC1250D3A@webabinitio.net> On Sun, 19 Jun 2011 15:40:01 -0400, Jim Jewett wrote: > Does this really need to be a bare except? No, but that's a separate bug report, which you are welcome to file. The issue I closed was about moving the existing code. -- R. David Murray http://www.bitdance.com From solipsis at pitrou.net Mon Jun 20 05:06:51 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 20 Jun 2011 05:06:51 +0200 Subject: [Python-checkins] Daily reference leaks (618b681660e0): sum=-23 Message-ID: results for 618b681660e0 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pyexpat leaked [-323, 0, 0] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogQ7pHNm', '-x'] From python-checkins at python.org Mon Jun 20 14:46:09 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 14:46:09 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_calculate=5Fpath=28=29_deco?= =?utf8?q?des_the_PYTHONPATH_environment_variable_from_the_locale?= Message-ID: http://hg.python.org/cpython/rev/f571ed28a9ba changeset: 70898:f571ed28a9ba user: Victor Stinner date: Mon Jun 20 14:45:54 2011 +0200 summary: calculate_path() decodes the PYTHONPATH environment variable from the locale encoding using _Py_char2wchar() instead of mbstowcs() to store undecodable bytes as surrogates characters (PEP 383) instead of ignoring silently the PYTHONPATH variable. files: Modules/getpath.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Modules/getpath.c b/Modules/getpath.c --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -406,7 +406,7 @@ static wchar_t delimiter[2] = {DELIM, '\0'}; static wchar_t separator[2] = {SEP, '\0'}; char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ - wchar_t rtpypath[MAXPATHLEN+1]; + wchar_t *rtpypath = NULL; wchar_t *home = Py_GetPythonHome(); char *_path = getenv("PATH"); wchar_t *path_buffer = NULL; @@ -606,12 +606,12 @@ bufsz = 0; if (_rtpypath) { - size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t)); - if (s == (size_t)-1 || s >=sizeof(rtpypath)) - /* XXX deal with errors more gracefully */ + size_t rtpypath_len; + rtpypath = _Py_char2wchar(_rtpypath, &rtpypath_len); + if (rtpypath != NULL) + bufsz += rtpypath_len + 1; + else _rtpypath = NULL; - if (_rtpypath) - bufsz += wcslen(rtpypath) + 1; } defpath = _pythonpath; @@ -645,7 +645,7 @@ } else { /* Run-time value of $PYTHONPATH goes first */ - if (_rtpypath) { + if (rtpypath) { wcscpy(buf, rtpypath); wcscat(buf, delimiter); } @@ -719,6 +719,8 @@ PyMem_Free(_pythonpath); PyMem_Free(_prefix); PyMem_Free(_exec_prefix); + if (rtpypath != NULL) + PyMem_Free(rtpypath); } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 15:01:05 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 15:01:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=236697=3A_=5Flsprof?= =?utf8?q?=3A_normalizeUserObj=28=29_doesn=27t_encode/decode_=28UTF-8=29_t?= =?utf8?q?he?= Message-ID: http://hg.python.org/cpython/rev/b87eac0369b5 changeset: 70899:b87eac0369b5 user: Victor Stinner date: Mon Jun 20 14:59:53 2011 +0200 summary: Issue #6697: _lsprof: normalizeUserObj() doesn't encode/decode (UTF-8) the module name anymore, only work on unicode strings. Therefore it doesn't truncate module names with embedded NUL characters, or fail if the module name contains surrogate characters (UTF-8 encoder fails on a surrogate character). Patch written by Alexander Belopolsky. files: Modules/_lsprof.c | 45 ++++++++++++++-------------------- 1 files changed, 19 insertions(+), 26 deletions(-) diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -176,36 +176,29 @@ if (fn->m_self == NULL) { /* built-in function: look up the module name */ PyObject *mod = fn->m_module; - const char *modname; - if (mod && PyUnicode_Check(mod)) { - /* XXX: The following will truncate module names with embedded - * null-characters. It is unlikely that this can happen in - * practice and the concequences are not serious enough to - * introduce extra checks here. - */ - modname = _PyUnicode_AsString(mod); - if (modname == NULL) { - modname = ""; - PyErr_Clear(); + PyObject *modname = NULL; + if (mod != NULL) { + if (PyUnicode_Check(mod)) { + modname = mod; + Py_INCREF(modname); + } + else if (PyModule_Check(mod)) { + modname = PyModule_GetNameObject(mod); + if (modname == NULL) + PyErr_Clear(); } } - else if (mod && PyModule_Check(mod)) { - modname = PyModule_GetName(mod); - if (modname == NULL) { - PyErr_Clear(); - modname = "builtins"; + if (modname != NULL) { + if (PyUnicode_CompareWithASCIIString(modname, "builtins") != 0) { + PyObject *result; + result = PyUnicode_FromFormat("<%U.%s>", modname, + fn->m_ml->ml_name); + Py_DECREF(modname); + return result; } + Py_DECREF(modname); } - else { - modname = "builtins"; - } - if (strcmp(modname, "builtins") != 0) - return PyUnicode_FromFormat("<%s.%s>", - modname, - fn->m_ml->ml_name); - else - return PyUnicode_FromFormat("<%s>", - fn->m_ml->ml_name); + return PyUnicode_FromFormat("<%s>", fn->m_ml->ml_name); } else { /* built-in method: try to return -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 15:01:07 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 15:01:07 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_find=5Fmodule=5Fpath=5Flist?= =?utf8?q?=28=29_fails_if_=5FPy=5Ffopen=28=29_failed_and_raised_an_excepti?= =?utf8?q?on?= Message-ID: http://hg.python.org/cpython/rev/7731d2ab4fd4 changeset: 70900:7731d2ab4fd4 user: Victor Stinner date: Mon Jun 20 15:01:10 2011 +0200 summary: find_module_path_list() fails if _Py_fopen() failed and raised an exception (UnicodeEncodeError). files: Python/import.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -1908,6 +1908,10 @@ fp = _Py_fopen(filename, filemode); if (fp == NULL) { Py_DECREF(filename); + if (PyErr_Occurred()) { + Py_DECREF(prefix); + return NULL; + } continue; } match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 15:42:35 2011 From: python-checkins at python.org (nick.coghlan) Date: Mon, 20 Jun 2011 15:42:35 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_Be_more_descriptive_when_d?= =?utf8?q?escribing_the_options_for_seeking_help_with_problems?= Message-ID: http://hg.python.org/devguide/rev/63f3521fe8f8 changeset: 435:63f3521fe8f8 user: Nick Coghlan date: Mon Jun 20 23:42:26 2011 +1000 summary: Be more descriptive when describing the options for seeking help with problems during development. A little redundancy is a virtue in this context (initial patch by Adam Woodbeck) files: help.rst | 52 +++++++++++++++++++++++++++++-------------- 1 files changed, 35 insertions(+), 17 deletions(-) diff --git a/help.rst b/help.rst --- a/help.rst +++ b/help.rst @@ -5,31 +5,32 @@ If you are working on Python it is very possible you will come across an issue where you need some assistance to solve it (this happens to core developers -all the time). Below are some options on getting help. +all the time). -If the question involves process or tool usage then please check other parts of -this guide first as it should answer your question. +Should you require help, there are a :ref:`variety of options available +` to seek assistance. If the question involves process or tool +usage then please check the rest of this guide first (especially the +:ref:`FAQ`) as it should answer your question. -Ask (#)python-dev +Ask #python-dev ----------------- -You have two avenues of communication out of the :ref:`myriad of options -available `. If you are comfortable with IRC you can try asking -on ``#python-dev`` (on the `freenode `_ network). -Typically there are a variety of experienced developers, ranging from -triagers to core developers, who can answer questions about developing for -Python. If you prefer email you can ask the `python-dev mailing-list -`_ for help with your -question. Just remember that both avenues are for questions involving the -development *of* Python, **not** for development *with* Python. +If you are comfortable with IRC you can try asking on ``#python-dev`` (on +the `freenode`_ network). Typically there are a number of experienced +developers, ranging from triagers to core developers, who can answer +questions about developing for Python. Just remember that ``#python-dev`` +is for questions involving the development *of* Python whereas ``#python`` +is for questions concerning development *with* Python. + +.. _freenode: http://freenode.net/ File a Bug ---------- If you strongly suspect you have stumbled on a bug (be it in the build -process, in the test suite, or in other areas), then open a issue on the +process, in the test suite, or in other areas), then open an issue on the `issue tracker`_. As with every bug report it is strongly advised that you detail which conditions triggered it (including the OS name and version, and what you were trying to do), as well as the exact error message you @@ -38,13 +39,30 @@ .. _issue tracker: http://bugs.python.org +Mailing Lists +------------- + +Further options for seeking assistance include the `python-ideas`_ and +`python-dev`_ mailing lists. Python-ideas contains discussion of speculative +Python language ideas for possible inclusion into the language. If an idea +gains traction it can then be discussed and honed to the point of becoming a +solid proposal and presented on python-dev. Python-dev contains discussion +of current Python design issues, release mechanics, and maintenance of +existing releases. As with ``#python-dev``, these mailing lists are for +questions involving the development *of* Python, **not** for development +*with* Python. + +.. _python-ideas: http://mail.python.org/mailman/listinfo/python-ideas +.. _python-dev: http://mail.python.org/mailman/listinfo/python-dev + + Core Mentorship --------------- If you are interested in improving Python and contributing to its development, -but don't yet feel entirely comfortable with the public channels mentioned -above `Python Mentors`_ are here to help you. Python is fortunate to have a -community of volunteer developers willing to mentor anyone wishing to +but don?t yet feel entirely comfortable with the public channels mentioned +above, `Python Mentors`_ are here to help you. Python is fortunate to have a +community of volunteer core developers willing to mentor anyone wishing to contribute code, work on bug fixes or improve documentation. Everyone is welcomed and encouraged to contribute. -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Mon Jun 20 16:14:54 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 16:14:54 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_call=5Ffind=5Fmodule=28=29_?= =?utf8?q?handles_dup=28=29_failure=3A_raise_an_OSError_exception?= Message-ID: http://hg.python.org/cpython/rev/b4a7cd376d6f changeset: 70901:b4a7cd376d6f user: Victor Stinner date: Mon Jun 20 15:16:55 2011 +0200 summary: call_find_module() handles dup() failure: raise an OSError exception files: Python/import.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -3567,6 +3567,10 @@ if (fd != -1) fd = dup(fd); fclose(fp); + if (fd == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } fp = NULL; } if (fd != -1) { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:14:55 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 16:14:55 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogQ2xvc2UgIzMwNjc6?= =?utf8?q?_locale=2Esetlocale=28=29_accepts_a_Unicode_locale=2E?= Message-ID: http://hg.python.org/cpython/rev/d370d609d09b changeset: 70902:d370d609d09b branch: 2.7 parent: 70891:6c16a31e0442 user: Victor Stinner date: Mon Jun 20 16:14:48 2011 +0200 summary: Close #3067: locale.setlocale() accepts a Unicode locale. files: Lib/locale.py | 2 +- Misc/NEWS | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/locale.py b/Lib/locale.py --- a/Lib/locale.py +++ b/Lib/locale.py @@ -525,7 +525,7 @@ category may be given as one of the LC_* values. """ - if locale and type(locale) is not type(""): + if locale and not isinstance(locale, basestring): # convert to string locale = normalize(_build_localename(locale)) return _setlocale(category, locale) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,8 @@ Library ------- +- Issue #3067: locale.setlocale() accepts a Unicode locale. + - Issue #11700: mailbox proxy object close methods can now be called multiple times without error, and _ProxyFile now closes the wrapped file. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:38:23 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 16:38:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_Issu?= =?utf8?q?e12359_-_Removing_a_confusing_sentence_from_the_previous_change?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/a57134dd8688 changeset: 70903:a57134dd8688 branch: 3.2 parent: 70896:d310cc1c3a5d user: Senthil Kumaran date: Mon Jun 20 07:30:34 2011 -0700 summary: Fix closes Issue12359 - Removing a confusing sentence from the previous change. files: Doc/tutorial/modules.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -160,13 +160,13 @@ .. index:: triple: module; search; path When a module named :mod:`spam` is imported, the interpreter searches for a -file named :file:`spam.py` in the directory containing the input script (or -the current directory), and then in the list of directories specified by the -environment variable :envvar:`PYTHONPATH`. This has the same syntax as the -shell variable :envvar:`PATH`, that is, a list of directory names. When -:envvar:`PYTHONPATH` is not set, or when the file is not found there, the -search continues in an installation-dependent default path; on Unix, this is -usually :file:`.:/usr/local/lib/python`. +file named :file:`spam.py` in the directory containing the input script and +then in the list of directories specified by the environment variable +:envvar:`PYTHONPATH`. This has the same syntax as the shell variable +:envvar:`PATH`, that is, a list of directory names. When :envvar:`PYTHONPATH` +is not set, or when the file is not found there, the search continues in an +installation-dependent default path; on Unix, this is usually +:file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:38:24 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 16:38:24 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2_-_Fix_closes_Issue12359_-_Removing_a_confus?= =?utf8?q?ing_sentence_from_the?= Message-ID: http://hg.python.org/cpython/rev/18ebc7809cb2 changeset: 70904:18ebc7809cb2 parent: 70900:7731d2ab4fd4 parent: 70903:a57134dd8688 user: Senthil Kumaran date: Mon Jun 20 07:33:25 2011 -0700 summary: merge from 3.2 - Fix closes Issue12359 - Removing a confusing sentence from the previous change. files: Doc/tutorial/modules.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -160,13 +160,13 @@ .. index:: triple: module; search; path When a module named :mod:`spam` is imported, the interpreter searches for a -file named :file:`spam.py` in the directory containing the input script (or -the current directory), and then in the list of directories specified by the -environment variable :envvar:`PYTHONPATH`. This has the same syntax as the -shell variable :envvar:`PATH`, that is, a list of directory names. When -:envvar:`PYTHONPATH` is not set, or when the file is not found there, the -search continues in an installation-dependent default path; on Unix, this is -usually :file:`.:/usr/local/lib/python`. +file named :file:`spam.py` in the directory containing the input script and +then in the list of directories specified by the environment variable +:envvar:`PYTHONPATH`. This has the same syntax as the shell variable +:envvar:`PATH`, that is, a list of directory names. When :envvar:`PYTHONPATH` +is not set, or when the file is not found there, the search continues in an +installation-dependent default path; on Unix, this is usually +:file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:38:24 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 16:38:24 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_merge_3=2E2_-_F?= =?utf8?q?ix_closes_Issue12359_-_Removing_a_confusing_sentence_from_the?= Message-ID: http://hg.python.org/cpython/rev/51ad2d4390bc changeset: 70905:51ad2d4390bc branch: 2.7 parent: 70891:6c16a31e0442 user: Senthil Kumaran date: Mon Jun 20 07:34:48 2011 -0700 summary: merge 3.2 - Fix closes Issue12359 - Removing a confusing sentence from the previous change. files: Doc/tutorial/modules.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -156,13 +156,13 @@ .. index:: triple: module; search; path When a module named :mod:`spam` is imported, the interpreter searches for a -file named :file:`spam.py` in the directory containing the input script (or the -current directory), and then in the list of directories specified by the -environment variable :envvar:`PYTHONPATH`. This has the same syntax as the -shell variable :envvar:`PATH`, that is, a list of directory names. When -:envvar:`PYTHONPATH` is not set, or when the file is not found there, the -search continues in an installation-dependent default path; on Unix, this is -usually :file:`.:/usr/local/lib/python`. +file named :file:`spam.py` in the directory containing the input script and +then in the list of directories specified by the environment variable +:envvar:`PYTHONPATH`. This has the same syntax as the shell variable +:envvar:`PATH`, that is, a list of directory names. When :envvar:`PYTHONPATH` +is not set, or when the file is not found there, the search continues in an +installation-dependent default path; on Unix, this is usually +:file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:38:25 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 16:38:25 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/41a23277a35a changeset: 70906:41a23277a35a branch: 2.7 parent: 70905:51ad2d4390bc parent: 70902:d370d609d09b user: Senthil Kumaran date: Mon Jun 20 07:37:03 2011 -0700 summary: merge heads files: Lib/locale.py | 2 +- Misc/NEWS | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/locale.py b/Lib/locale.py --- a/Lib/locale.py +++ b/Lib/locale.py @@ -525,7 +525,7 @@ category may be given as one of the LC_* values. """ - if locale and type(locale) is not type(""): + if locale and not isinstance(locale, basestring): # convert to string locale = normalize(_build_localename(locale)) return _setlocale(category, locale) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,8 @@ Library ------- +- Issue #3067: locale.setlocale() accepts a Unicode locale. + - Issue #11700: mailbox proxy object close methods can now be called multiple times without error, and _ProxyFile now closes the wrapped file. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 16:38:26 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 20 Jun 2011 16:38:26 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/d84760f1dcbe changeset: 70907:d84760f1dcbe parent: 70904:18ebc7809cb2 parent: 70901:b4a7cd376d6f user: Senthil Kumaran date: Mon Jun 20 07:37:59 2011 -0700 summary: merge heads files: Python/import.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -3567,6 +3567,10 @@ if (fd != -1) fd = dup(fd); fclose(fp); + if (fd == -1) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } fp = NULL; } if (fd != -1) { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 17:46:59 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 17:46:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Close_=2312289=3A_Fix_=22is?= =?utf8?q?_executable=3F=22_test_in_the_CGI_server?= Message-ID: http://hg.python.org/cpython/rev/ecef74419d55 changeset: 70908:ecef74419d55 user: Victor Stinner date: Mon Jun 20 17:45:54 2011 +0200 summary: Close #12289: Fix "is executable?" test in the CGI server Use os.access(path, os.X_OK) instead of (os.stat(path).st_mode & 0o111 != 0), and ignore the test on Windows. files: Lib/http/server.py | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Lib/http/server.py b/Lib/http/server.py --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -897,11 +897,7 @@ def executable(path): """Test for executable file.""" - try: - st = os.stat(path) - except os.error: - return False - return st.st_mode & 0o111 != 0 + return os.access(path, os.X_OK) class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): @@ -1015,7 +1011,7 @@ scriptname) return ispy = self.is_python(scriptname) - if not ispy: + if self.have_fork or not ispy: if not self.is_executable(scriptfile): self.send_error(403, "CGI script is not executable (%r)" % scriptname) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 17:55:41 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 17:55:41 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMjg1?= =?utf8?q?=3A_multiprocessing=2EPool=28=29_raises_a_ValueError_if_the_numb?= =?utf8?q?er_of?= Message-ID: http://hg.python.org/cpython/rev/1f171dd21bdb changeset: 70909:1f171dd21bdb branch: 3.2 parent: 70903:a57134dd8688 user: Victor Stinner date: Mon Jun 20 17:53:35 2011 +0200 summary: Issue #12285: multiprocessing.Pool() raises a ValueError if the number of processes if negative or null. files: Lib/multiprocessing/pool.py | 2 ++ Lib/test/test_multiprocessing.py | 3 +++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -148,6 +148,8 @@ processes = cpu_count() except NotImplementedError: processes = 1 + if processes < 1: + raise ValueError("Number of processes must be at least 1") if initializer is not None and not hasattr(initializer, '__call__'): raise TypeError('initializer must be a callable') diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1089,6 +1089,9 @@ self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) def test_make_pool(self): + self.assertRaises(ValueError, multiprocessing.Pool, -1) + self.assertRaises(ValueError, multiprocessing.Pool, 0) + p = multiprocessing.Pool(3) self.assertEqual(3, len(p._pool)) p.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 17:55:42 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 17:55:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312285=3A_multiprocessing=2EPool?= =?utf8?q?=28=29_raises_a_ValueError_if_the?= Message-ID: http://hg.python.org/cpython/rev/1861683793d9 changeset: 70910:1861683793d9 parent: 70908:ecef74419d55 parent: 70909:1f171dd21bdb user: Victor Stinner date: Mon Jun 20 17:54:03 2011 +0200 summary: (merge 3.2) Issue #12285: multiprocessing.Pool() raises a ValueError if the number of processes if negative or null. files: Lib/multiprocessing/pool.py | 2 ++ Lib/test/test_multiprocessing.py | 3 +++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -148,6 +148,8 @@ processes = cpu_count() except NotImplementedError: processes = 1 + if processes < 1: + raise ValueError("Number of processes must be at least 1") if initializer is not None and not hasattr(initializer, '__call__'): raise TypeError('initializer must be a callable') diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1138,6 +1138,9 @@ self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) def test_make_pool(self): + self.assertRaises(ValueError, multiprocessing.Pool, -1) + self.assertRaises(ValueError, multiprocessing.Pool, 0) + p = multiprocessing.Pool(3) self.assertEqual(3, len(p._pool)) p.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 17:55:43 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 17:55:43 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMjg1?= =?utf8?q?=3A_multiprocessing=2EPool=28=29_raises_a_ValueError_if_the_numb?= =?utf8?q?er_of?= Message-ID: http://hg.python.org/cpython/rev/815263546757 changeset: 70911:815263546757 branch: 2.7 parent: 70906:41a23277a35a user: Victor Stinner date: Mon Jun 20 17:54:33 2011 +0200 summary: Issue #12285: multiprocessing.Pool() raises a ValueError if the number of processes if negative or null. files: Lib/multiprocessing/pool.py | 2 ++ Lib/test/test_multiprocessing.py | 3 +++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -125,6 +125,8 @@ processes = cpu_count() except NotImplementedError: processes = 1 + if processes < 1: + raise ValueError("Number of processes must be at least 1") if initializer is not None and not hasattr(initializer, '__call__'): raise TypeError('initializer must be a callable') diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1085,6 +1085,9 @@ self.assertEqual(sorted(it), map(sqr, range(1000))) def test_make_pool(self): + self.assertRaises(ValueError, multiprocessing.Pool, -1) + self.assertRaises(ValueError, multiprocessing.Pool, 0) + p = multiprocessing.Pool(3) self.assertEqual(3, len(p._pool)) p.close() -- Repository URL: http://hg.python.org/cpython From tjreedy at udel.edu Mon Jun 20 18:52:41 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 20 Jun 2011 12:52:41 -0400 Subject: [Python-checkins] cpython (2.7): Close #3067: locale.setlocale() accepts a Unicode locale. In-Reply-To: References: Message-ID: <4DFF7AD9.20807@udel.edu> On 6/20/2011 10:14 AM, victor.stinner wrote: > http://hg.python.org/cpython/rev/d370d609d09b > changeset: 70902:d370d609d09b > branch: 2.7 > parent: 70891:6c16a31e0442 > user: Victor Stinner > date: Mon Jun 20 16:14:48 2011 +0200 > summary: > Close #3067: locale.setlocale() accepts a Unicode locale. For the reasons I gave on the tracker, after careful consideration, I consider this to be a feature addition and recommended rejection of the change. I think this should be reverted. > files: > Lib/locale.py | 2 +- > Misc/NEWS | 2 ++ > 2 files changed, 3 insertions(+), 1 deletions(-) > > > diff --git a/Lib/locale.py b/Lib/locale.py > --- a/Lib/locale.py > +++ b/Lib/locale.py > @@ -525,7 +525,7 @@ > category may be given as one of the LC_* values. > > """ > - if locale and type(locale) is not type(""): > + if locale and not isinstance(locale, basestring): > # convert to string > locale = normalize(_build_localename(locale)) > return _setlocale(category, locale) > diff --git a/Misc/NEWS b/Misc/NEWS > --- a/Misc/NEWS > +++ b/Misc/NEWS > @@ -16,6 +16,8 @@ > Library > ------- > > +- Issue #3067: locale.setlocale() accepts a Unicode locale. You yourself said this is useless because it cannot be used in previous versions of 2.7. -- Terry Jan Reedy From python-checkins at python.org Mon Jun 20 22:07:06 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 22:07:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Revert_d370d609?= =?utf8?q?d09b_as_requested_by_Terry_Jan_Reedy=3A?= Message-ID: http://hg.python.org/cpython/rev/e72a2a60316f changeset: 70912:e72a2a60316f branch: 2.7 user: Victor Stinner date: Mon Jun 20 22:07:06 2011 +0200 summary: Revert d370d609d09b as requested by Terry Jan Reedy: "#3067: locale.setlocale() accepts a Unicode locale." files: Lib/locale.py | 2 +- Misc/NEWS | 2 -- 2 files changed, 1 insertions(+), 3 deletions(-) diff --git a/Lib/locale.py b/Lib/locale.py --- a/Lib/locale.py +++ b/Lib/locale.py @@ -525,7 +525,7 @@ category may be given as one of the LC_* values. """ - if locale and not isinstance(locale, basestring): + if locale and type(locale) is not type(""): # convert to string locale = normalize(_build_localename(locale)) return _setlocale(category, locale) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,8 +16,6 @@ Library ------- -- Issue #3067: locale.setlocale() accepts a Unicode locale. - - Issue #11700: mailbox proxy object close methods can now be called multiple times without error, and _ProxyFile now closes the wrapped file. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 20 23:28:04 2011 From: python-checkins at python.org (victor.stinner) Date: Mon, 20 Jun 2011 23:28:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Close_=2312363=3A_fix_a_rac?= =?utf8?q?e_condition_in_siginterrupt=28=29_tests?= Message-ID: http://hg.python.org/cpython/rev/968b9ff9a059 changeset: 70913:968b9ff9a059 parent: 70910:1861683793d9 user: Victor Stinner date: Mon Jun 20 23:28:09 2011 +0200 summary: Close #12363: fix a race condition in siginterrupt() tests The previous tests used time.sleep() to synchronize two processes. If the host was too slow, the test could fail. The new tests only use one process, but they use a subprocess to: - have only one thread - have a timeout on the blocking read (select cannot be used in the test, select always fail with EINTR, the kernel doesn't restart it) - not touch signal handling of the parent process files: Lib/test/test_signal.py | 120 +++++++++++---------------- 1 files changed, 48 insertions(+), 72 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -9,7 +9,7 @@ import subprocess import traceback import sys, os, time, errno -from test.script_helper import assert_python_ok +from test.script_helper import assert_python_ok, spawn_python try: import threading except ImportError: @@ -314,100 +314,76 @@ @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class SiginterruptTest(unittest.TestCase): - def setUp(self): - """Install a no-op signal handler that can be set to allow - interrupts or not, and arrange for the original signal handler to be - re-installed when the test is finished. - """ - self.signum = signal.SIGUSR1 - oldhandler = signal.signal(self.signum, lambda x,y: None) - self.addCleanup(signal.signal, self.signum, oldhandler) - - def readpipe_interrupted(self): + def readpipe_interrupted(self, interrupt): """Perform a read during which a signal will arrive. Return True if the read is interrupted by the signal and raises an exception. Return False if it returns normally. """ - # Create a pipe that can be used for the read. Also clean it up - # when the test is over, since nothing else will (but see below for - # the write end). - r, w = os.pipe() - self.addCleanup(os.close, r) + # use a subprocess to have only one thread, to have a timeout on the + # blocking read and to not touch signal handling in this process + code = """if 1: + import errno + import os + import signal + import sys - # Create another process which can send a signal to this one to try - # to interrupt the read. - ppid = os.getpid() - pid = os.fork() + interrupt = %r + r, w = os.pipe() - if pid == 0: - # Child code: sleep to give the parent enough time to enter the - # read() call (there's a race here, but it's really tricky to - # eliminate it); then signal the parent process. Also, sleep - # again to make it likely that the signal is delivered to the - # parent process before the child exits. If the child exits - # first, the write end of the pipe will be closed and the test - # is invalid. + def handler(signum, frame): + pass + + signal.signal(signal.SIGALRM, handler) + if interrupt is not None: + signal.siginterrupt(signal.SIGALRM, interrupt) + + # run the test twice + for loop in range(2): + # send a SIGALRM in a second (during the read) + signal.alarm(1) + try: + # blocking call: read from a pipe without data + os.read(r, 1) + except OSError as err: + if err.errno != errno.EINTR: + raise + else: + sys.exit(2) + sys.exit(3) + """ % (interrupt,) + with spawn_python('-c', code) as process: try: - time.sleep(0.2) - os.kill(ppid, self.signum) - time.sleep(0.2) - finally: - # No matter what, just exit as fast as possible now. - exit_subprocess() - else: - # Parent code. - # Make sure the child is eventually reaped, else it'll be a - # zombie for the rest of the test suite run. - self.addCleanup(os.waitpid, pid, 0) - - # Close the write end of the pipe. The child has a copy, so - # it's not really closed until the child exits. We need it to - # close when the child exits so that in the non-interrupt case - # the read eventually completes, otherwise we could just close - # it *after* the test. - os.close(w) - - # Try the read and report whether it is interrupted or not to - # the caller. - try: - d = os.read(r, 1) + stdout, stderr = process.communicate(timeout=3.0) + except subprocess.TimeoutExpired: + process.kill() return False - except OSError as err: - if err.errno != errno.EINTR: - raise - return True + else: + exitcode = process.wait() + if exitcode not in (2, 3): + raise Exception("Child error (exit code %s): %s" + % (exitcode, stdout)) + return (exitcode == 3) def test_without_siginterrupt(self): # If a signal handler is installed and siginterrupt is not called # at all, when that signal arrives, it interrupts a syscall that's in # progress. - i = self.readpipe_interrupted() - self.assertTrue(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertTrue(i) + interrupted = self.readpipe_interrupted(None) + self.assertTrue(interrupted) def test_siginterrupt_on(self): # If a signal handler is installed and siginterrupt is called with # a true value for the second argument, when that signal arrives, it # interrupts a syscall that's in progress. - signal.siginterrupt(self.signum, 1) - i = self.readpipe_interrupted() - self.assertTrue(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertTrue(i) + interrupted = self.readpipe_interrupted(True) + self.assertTrue(interrupted) def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it # does not interrupt a syscall that's in progress. - signal.siginterrupt(self.signum, 0) - i = self.readpipe_interrupted() - self.assertFalse(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertFalse(i) + interrupted = self.readpipe_interrupted(False) + self.assertFalse(interrupted) @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 02:20:50 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 02:20:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_intrcheck=2Ec=2C_whi?= =?utf8?q?ch_hasn=27t_been_used_for_years?= Message-ID: http://hg.python.org/cpython/rev/a8977b1b6115 changeset: 70914:a8977b1b6115 parent: 70910:1861683793d9 user: Benjamin Peterson date: Mon Jun 20 19:22:34 2011 -0500 summary: remove intrcheck.c, which hasn't been used for years files: Parser/intrcheck.c | 174 --------------------------------- 1 files changed, 0 insertions(+), 174 deletions(-) diff --git a/Parser/intrcheck.c b/Parser/intrcheck.c deleted file mode 100644 --- a/Parser/intrcheck.c +++ /dev/null @@ -1,174 +0,0 @@ - -/* Check for interrupts */ - -#include "Python.h" -#include "pythread.h" - -#ifdef QUICKWIN - -#include - -void -PyOS_InitInterrupts(void) -{ -} - -void -PyOS_FiniInterrupts(void) -{ -} - -int -PyOS_InterruptOccurred(void) -{ - _wyield(); -} - -#define OK - -#endif /* QUICKWIN */ - -#if defined(_M_IX86) && !defined(__QNX__) -#include -#endif - -#if defined(MSDOS) && !defined(QUICKWIN) - -#ifdef __GNUC__ - -/* This is for DJGPP's GO32 extender. I don't know how to trap - * control-C (There's no API for ctrl-C, and I don't want to mess with - * the interrupt vectors.) However, this DOES catch control-break. - * --Amrit - */ - -#include - -void -PyOS_InitInterrupts(void) -{ - _go32_want_ctrl_break(1 /* TRUE */); -} - -void -PyOS_FiniInterrupts(void) -{ -} - -int -PyOS_InterruptOccurred(void) -{ - return _go32_was_ctrl_break_hit(); -} - -#else /* !__GNUC__ */ - -/* This might work for MS-DOS (untested though): */ - -void -PyOS_InitInterrupts(void) -{ -} - -void -PyOS_FiniInterrupts(void) -{ -} - -int -PyOS_InterruptOccurred(void) -{ - int interrupted = 0; - while (kbhit()) { - if (getch() == '\003') - interrupted = 1; - } - return interrupted; -} - -#endif /* __GNUC__ */ - -#define OK - -#endif /* MSDOS && !QUICKWIN */ - - -#ifndef OK - -/* Default version -- for real operating systems and for Standard C */ - -#include -#include -#include - -static int interrupted; - -void -PyErr_SetInterrupt(void) -{ - interrupted = 1; -} - -extern int PyErr_CheckSignals(void); - -static int -checksignals_witharg(void * arg) -{ - return PyErr_CheckSignals(); -} - -static void -intcatcher(int sig) -{ - extern void Py_Exit(int); - static char message[] = -"python: to interrupt a truly hanging Python program, interrupt once more.\n"; - switch (interrupted++) { - case 0: - break; - case 1: - write(2, message, strlen(message)); - break; - case 2: - interrupted = 0; - Py_Exit(1); - break; - } - PyOS_setsig(SIGINT, intcatcher); - Py_AddPendingCall(checksignals_witharg, NULL); -} - -static void (*old_siginthandler)(int) = SIG_DFL; - -void -PyOS_InitInterrupts(void) -{ - if ((old_siginthandler = PyOS_setsig(SIGINT, SIG_IGN)) != SIG_IGN) - PyOS_setsig(SIGINT, intcatcher); -} - -void -PyOS_FiniInterrupts(void) -{ - PyOS_setsig(SIGINT, old_siginthandler); -} - -int -PyOS_InterruptOccurred(void) -{ - if (!interrupted) - return 0; - interrupted = 0; - return 1; -} - -#endif /* !OK */ - -void -PyOS_AfterFork(void) -{ -#ifdef WITH_THREAD - PyEval_ReInitThreads(); - PyThread_ReInitTLS(); -#endif -} -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 02:20:51 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 02:20:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/9713f1e2a159 changeset: 70915:9713f1e2a159 parent: 70914:a8977b1b6115 parent: 70913:968b9ff9a059 user: Benjamin Peterson date: Mon Jun 20 19:24:31 2011 -0500 summary: merge heads files: Lib/test/test_signal.py | 120 +++++++++++---------------- 1 files changed, 48 insertions(+), 72 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -9,7 +9,7 @@ import subprocess import traceback import sys, os, time, errno -from test.script_helper import assert_python_ok +from test.script_helper import assert_python_ok, spawn_python try: import threading except ImportError: @@ -314,100 +314,76 @@ @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class SiginterruptTest(unittest.TestCase): - def setUp(self): - """Install a no-op signal handler that can be set to allow - interrupts or not, and arrange for the original signal handler to be - re-installed when the test is finished. - """ - self.signum = signal.SIGUSR1 - oldhandler = signal.signal(self.signum, lambda x,y: None) - self.addCleanup(signal.signal, self.signum, oldhandler) - - def readpipe_interrupted(self): + def readpipe_interrupted(self, interrupt): """Perform a read during which a signal will arrive. Return True if the read is interrupted by the signal and raises an exception. Return False if it returns normally. """ - # Create a pipe that can be used for the read. Also clean it up - # when the test is over, since nothing else will (but see below for - # the write end). - r, w = os.pipe() - self.addCleanup(os.close, r) + # use a subprocess to have only one thread, to have a timeout on the + # blocking read and to not touch signal handling in this process + code = """if 1: + import errno + import os + import signal + import sys - # Create another process which can send a signal to this one to try - # to interrupt the read. - ppid = os.getpid() - pid = os.fork() + interrupt = %r + r, w = os.pipe() - if pid == 0: - # Child code: sleep to give the parent enough time to enter the - # read() call (there's a race here, but it's really tricky to - # eliminate it); then signal the parent process. Also, sleep - # again to make it likely that the signal is delivered to the - # parent process before the child exits. If the child exits - # first, the write end of the pipe will be closed and the test - # is invalid. + def handler(signum, frame): + pass + + signal.signal(signal.SIGALRM, handler) + if interrupt is not None: + signal.siginterrupt(signal.SIGALRM, interrupt) + + # run the test twice + for loop in range(2): + # send a SIGALRM in a second (during the read) + signal.alarm(1) + try: + # blocking call: read from a pipe without data + os.read(r, 1) + except OSError as err: + if err.errno != errno.EINTR: + raise + else: + sys.exit(2) + sys.exit(3) + """ % (interrupt,) + with spawn_python('-c', code) as process: try: - time.sleep(0.2) - os.kill(ppid, self.signum) - time.sleep(0.2) - finally: - # No matter what, just exit as fast as possible now. - exit_subprocess() - else: - # Parent code. - # Make sure the child is eventually reaped, else it'll be a - # zombie for the rest of the test suite run. - self.addCleanup(os.waitpid, pid, 0) - - # Close the write end of the pipe. The child has a copy, so - # it's not really closed until the child exits. We need it to - # close when the child exits so that in the non-interrupt case - # the read eventually completes, otherwise we could just close - # it *after* the test. - os.close(w) - - # Try the read and report whether it is interrupted or not to - # the caller. - try: - d = os.read(r, 1) + stdout, stderr = process.communicate(timeout=3.0) + except subprocess.TimeoutExpired: + process.kill() return False - except OSError as err: - if err.errno != errno.EINTR: - raise - return True + else: + exitcode = process.wait() + if exitcode not in (2, 3): + raise Exception("Child error (exit code %s): %s" + % (exitcode, stdout)) + return (exitcode == 3) def test_without_siginterrupt(self): # If a signal handler is installed and siginterrupt is not called # at all, when that signal arrives, it interrupts a syscall that's in # progress. - i = self.readpipe_interrupted() - self.assertTrue(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertTrue(i) + interrupted = self.readpipe_interrupted(None) + self.assertTrue(interrupted) def test_siginterrupt_on(self): # If a signal handler is installed and siginterrupt is called with # a true value for the second argument, when that signal arrives, it # interrupts a syscall that's in progress. - signal.siginterrupt(self.signum, 1) - i = self.readpipe_interrupted() - self.assertTrue(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertTrue(i) + interrupted = self.readpipe_interrupted(True) + self.assertTrue(interrupted) def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it # does not interrupt a syscall that's in progress. - signal.siginterrupt(self.signum, 0) - i = self.readpipe_interrupted() - self.assertFalse(i) - # Arrival of the signal shouldn't have changed anything. - i = self.readpipe_interrupted() - self.assertFalse(i) + interrupted = self.readpipe_interrupted(False) + self.assertFalse(interrupted) @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 04:38:10 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 04:38:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_fix_indentation?= Message-ID: http://hg.python.org/cpython/rev/8ece0dacd8e8 changeset: 70916:8ece0dacd8e8 branch: 3.2 parent: 70880:9e58a638f028 user: Benjamin Peterson date: Mon Jun 20 21:40:19 2011 -0500 summary: fix indentation files: Python/ast.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Python/ast.c b/Python/ast.c --- a/Python/ast.c +++ b/Python/ast.c @@ -2283,7 +2283,7 @@ loop: switch (TYPE(n)) { - case import_as_name: { + case import_as_name: { node *name_node = CHILD(n, 0); str = NULL; name = NEW_IDENTIFIER(name_node); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 04:38:11 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 04:38:11 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/c38c3dab4bfb changeset: 70917:c38c3dab4bfb branch: 3.2 parent: 70916:8ece0dacd8e8 parent: 70909:1f171dd21bdb user: Benjamin Peterson date: Mon Jun 20 21:40:34 2011 -0500 summary: merge heads files: Doc/library/asyncore.rst | 4 ++-- Doc/library/http.client.rst | 13 ++++++++++++- Doc/tutorial/modules.rst | 15 ++++++++------- Lib/multiprocessing/pool.py | 2 ++ Lib/test/test_multiprocessing.py | 3 +++ 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -157,8 +157,8 @@ Called on listening channels (passive openers) when a connection has been established with a new remote endpoint that has issued a :meth:`connect` - call for the local endpoint. *conn* is a *new* socket object usable to - send and receive data on the connection, and *address* is the address + call for the local endpoint. *sock* is a *new* socket object usable to + send and receive data on the connection, and *addr* is the address bound to the socket on the other end of the connection. .. versionadded:: 3.2 diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -543,6 +543,9 @@ A debugging hook. If :attr:`debuglevel` is greater than zero, messages will be printed to stdout as the response is read and parsed. +.. attribute:: HTTPResponse.closed + + Is True if the stream is closed. Examples -------- @@ -555,7 +558,15 @@ >>> r1 = conn.getresponse() >>> print(r1.status, r1.reason) 200 OK - >>> data1 = r1.read() + >>> data1 = r1.read() # This will return entire content. + >>> # The following example demonstrates reading data in chunks. + >>> conn.request("GET", "/index.html") + >>> r1 = conn.getresponse() + >>> while not r1.closed: + ... print(r1.read(200)) # 200 bytes + b'>> # Example of an invalid request >>> conn.request("GET", "/parrot.spam") >>> r2 = conn.getresponse() >>> print(r2.status, r2.reason) diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -159,13 +159,14 @@ .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter searches for a file -named :file:`spam.py` in the current directory, and then in the list of -directories specified by the environment variable :envvar:`PYTHONPATH`. This -has the same syntax as the shell variable :envvar:`PATH`, that is, a list of -directory names. When :envvar:`PYTHONPATH` is not set, or when the file is not -found there, the search continues in an installation-dependent default path; on -Unix, this is usually :file:`.:/usr/local/lib/python`. +When a module named :mod:`spam` is imported, the interpreter searches for a +file named :file:`spam.py` in the directory containing the input script and +then in the list of directories specified by the environment variable +:envvar:`PYTHONPATH`. This has the same syntax as the shell variable +:envvar:`PATH`, that is, a list of directory names. When :envvar:`PYTHONPATH` +is not set, or when the file is not found there, the search continues in an +installation-dependent default path; on Unix, this is usually +:file:`.:/usr/local/lib/python`. Actually, modules are searched in the list of directories given by the variable ``sys.path`` which is initialized from the directory containing the input script diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -148,6 +148,8 @@ processes = cpu_count() except NotImplementedError: processes = 1 + if processes < 1: + raise ValueError("Number of processes must be at least 1") if initializer is not None and not hasattr(initializer, '__call__'): raise TypeError('initializer must be a callable') diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@ -1089,6 +1089,9 @@ self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) def test_make_pool(self): + self.assertRaises(ValueError, multiprocessing.Pool, -1) + self.assertRaises(ValueError, multiprocessing.Pool, 0) + p = multiprocessing.Pool(3) self.assertEqual(3, len(p._pool)) p.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 04:38:12 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 04:38:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/c624fd54263c changeset: 70918:c624fd54263c parent: 70915:9713f1e2a159 parent: 70917:c38c3dab4bfb user: Benjamin Peterson date: Mon Jun 20 21:40:46 2011 -0500 summary: merge 3.2 files: Python/ast.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Python/ast.c b/Python/ast.c --- a/Python/ast.c +++ b/Python/ast.c @@ -2283,7 +2283,7 @@ loop: switch (TYPE(n)) { - case import_as_name: { + case import_as_name: { node *name_node = CHILD(n, 0); str = NULL; name = NEW_IDENTIFIER(name_node); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 05:05:35 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 05:05:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_fix_indentation?= Message-ID: http://hg.python.org/cpython/rev/275862274567 changeset: 70919:275862274567 branch: 3.2 parent: 70917:c38c3dab4bfb user: Benjamin Peterson date: Mon Jun 20 22:09:13 2011 -0500 summary: fix indentation files: Python/symtable.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1568,12 +1568,12 @@ } else { if (st->st_cur->ste_type != ModuleBlock) { - int lineno = st->st_cur->ste_lineno; - int col_offset = st->st_cur->ste_col_offset; - PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset); - Py_DECREF(store_name); - return 0; + int lineno = st->st_cur->ste_lineno; + int col_offset = st->st_cur->ste_col_offset; + PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); + PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset); + Py_DECREF(store_name); + return 0; } st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; Py_DECREF(store_name); -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 05:05:35 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 21 Jun 2011 05:05:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/c8192197d23d changeset: 70920:c8192197d23d parent: 70918:c624fd54263c parent: 70919:275862274567 user: Benjamin Peterson date: Mon Jun 20 22:09:20 2011 -0500 summary: merge 3.2 files: Python/symtable.c | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1576,12 +1576,12 @@ } else { if (st->st_cur->ste_type != ModuleBlock) { - int lineno = st->st_cur->ste_lineno; - int col_offset = st->st_cur->ste_col_offset; - PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); - PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset); - Py_DECREF(store_name); - return 0; + int lineno = st->st_cur->ste_lineno; + int col_offset = st->st_cur->ste_col_offset; + PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING); + PyErr_SyntaxLocationEx(st->st_filename, lineno, col_offset); + Py_DECREF(store_name); + return 0; } st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; Py_DECREF(store_name); -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Tue Jun 21 05:07:39 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 21 Jun 2011 05:07:39 +0200 Subject: [Python-checkins] Daily reference leaks (9713f1e2a159): sum=244 Message-ID: results for 9713f1e2a159 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pyexpat leaked [0, 0, -56] references, sum=-56 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflog0SGxH1', '-x'] From python-checkins at python.org Tue Jun 21 17:24:17 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 21 Jun 2011 17:24:17 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogQ2xvc2UgIzEyMzgz?= =?utf8?q?=3A_Fix_subprocess_module_with_env=3D=7B=7D=3A_don=27t_copy_the_?= =?utf8?q?environment?= Message-ID: http://hg.python.org/cpython/rev/b5963fceddad changeset: 70921:b5963fceddad branch: 3.2 parent: 70919:275862274567 user: Victor Stinner date: Tue Jun 21 17:18:38 2011 +0200 summary: Close #12383: Fix subprocess module with env={}: don't copy the environment variables, start with an empty environment. files: Lib/subprocess.py | 2 +- Lib/test/test_subprocess.py | 23 ++++++++++++++++------- Misc/NEWS | 3 +++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1169,7 +1169,7 @@ # potential deadlocks, thus we do all this here. # and pass it to fork_exec() - if env: + if env is not None: env_list = [os.fsencode(k) + b'=' + os.fsencode(v) for k, v in env.items()] else: diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -331,13 +331,22 @@ def test_env(self): newenv = os.environ.copy() newenv["FRUIT"] = "orange" - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(os.getenv("FRUIT"))'], - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read(), b"orange") + with subprocess.Popen([sys.executable, "-c", + 'import sys,os;' + 'sys.stdout.write(os.getenv("FRUIT"))'], + stdout=subprocess.PIPE, + env=newenv) as p: + stdout, stderr = p.communicate() + self.assertEqual(stdout, b"orange") + + def test_empty_env(self): + with subprocess.Popen([sys.executable, "-c", + 'import os; ' + 'print(len(os.environ))'], + stdout=subprocess.PIPE, + env={}) as p: + stdout, stderr = p.communicate() + self.assertEqual(stdout.strip(), b"0") def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #12383: Fix subprocess module with env={}: don't copy the environment + variables, start with an empty environment. + - Issue #11584: email.header.decode_header no longer fails if the header passed to it is a Header object, and Header/make_header no longer fail if given binary unknown-8bit input. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 17:24:18 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 21 Jun 2011 17:24:18 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Close_=2312383=3A_Fix_subprocess_module_wi?= =?utf8?q?th_env=3D=7B=7D=3A_don=27t_copy_the?= Message-ID: http://hg.python.org/cpython/rev/10ecf8576eb2 changeset: 70922:10ecf8576eb2 parent: 70920:c8192197d23d parent: 70921:b5963fceddad user: Victor Stinner date: Tue Jun 21 17:24:21 2011 +0200 summary: (merge 3.2) Close #12383: Fix subprocess module with env={}: don't copy the environment variables, start with an empty environment. files: Lib/subprocess.py | 2 +- Lib/test/test_subprocess.py | 23 ++++++++++++++++------- Misc/NEWS | 3 +++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1250,7 +1250,7 @@ # potential deadlocks, thus we do all this here. # and pass it to fork_exec() - if env: + if env is not None: env_list = [os.fsencode(k) + b'=' + os.fsencode(v) for k, v in env.items()] else: diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -382,13 +382,22 @@ def test_env(self): newenv = os.environ.copy() newenv["FRUIT"] = "orange" - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(os.getenv("FRUIT"))'], - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read(), b"orange") + with subprocess.Popen([sys.executable, "-c", + 'import sys,os;' + 'sys.stdout.write(os.getenv("FRUIT"))'], + stdout=subprocess.PIPE, + env=newenv) as p: + stdout, stderr = p.communicate() + self.assertEqual(stdout, b"orange") + + def test_empty_env(self): + with subprocess.Popen([sys.executable, "-c", + 'import os; ' + 'print(len(os.environ))'], + stdout=subprocess.PIPE, + env={}) as p: + stdout, stderr = p.communicate() + self.assertEqual(stdout.strip(), b"0") def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -196,6 +196,9 @@ Library ------- +- Issue #12383: Fix subprocess module with env={}: don't copy the environment + variables, start with an empty environment. + - Issue #11637: Fix support for importing packaging setup hooks from the project directory. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 21:59:03 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 21 Jun 2011 21:59:03 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMzgz?= =?utf8?q?=3A_skip_test=5Fempty=5Fenv=28=29_if_compiled_is_compiled_in_sha?= =?utf8?q?red_mode?= Message-ID: http://hg.python.org/cpython/rev/8d46e84cd812 changeset: 70923:8d46e84cd812 branch: 3.2 parent: 70921:b5963fceddad user: Victor Stinner date: Tue Jun 21 21:59:06 2011 +0200 summary: Issue #12383: skip test_empty_env() if compiled is compiled in shared mode Try also to get more informations about the Mac OS X failure: display the keys of the environment, instead of just the number of variables. files: Lib/test/test_subprocess.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -339,14 +339,17 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") + @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') == 1, + 'the python library cannot be loaded ' + 'with an empty environment') def test_empty_env(self): with subprocess.Popen([sys.executable, "-c", 'import os; ' - 'print(len(os.environ))'], + 'print(list(os.environ.keys()))'], stdout=subprocess.PIPE, env={}) as p: stdout, stderr = p.communicate() - self.assertEqual(stdout.strip(), b"0") + self.assertEqual(stdout.strip(), b"[]") def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 21 22:00:03 2011 From: python-checkins at python.org (victor.stinner) Date: Tue, 21 Jun 2011 22:00:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiAobWVyZ2UgMy4yKSBJc3N1ZSAjMTIzODM6IHNraXAgdGVzdF9lbXB0eV9lbnYo?= =?utf8?q?=29_if_compiled_is_compiled_in?= Message-ID: http://hg.python.org/cpython/rev/d1d5a7392e39 changeset: 70924:d1d5a7392e39 parent: 70922:10ecf8576eb2 parent: 70923:8d46e84cd812 user: Victor Stinner date: Tue Jun 21 21:59:51 2011 +0200 summary: (merge 3.2) Issue #12383: skip test_empty_env() if compiled is compiled in shared mode Try also to get more informations about the Mac OS X failure: display the keys of the environment, instead of just the number of variables. files: Lib/test/test_subprocess.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -390,14 +390,17 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") + @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') == 1, + 'the python library cannot be loaded ' + 'with an empty environment') def test_empty_env(self): with subprocess.Popen([sys.executable, "-c", 'import os; ' - 'print(len(os.environ))'], + 'print(list(os.environ.keys()))'], stdout=subprocess.PIPE, env={}) as p: stdout, stderr = p.communicate() - self.assertEqual(stdout.strip(), b"0") + self.assertEqual(stdout.strip(), b"[]") def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Wed Jun 22 05:07:36 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 22 Jun 2011 05:07:36 +0200 Subject: [Python-checkins] Daily reference leaks (d1d5a7392e39): sum=33 Message-ID: results for d1d5a7392e39 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pyexpat leaked [-267, 0, 0] references, sum=-267 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogDoZEbk', '-x'] From python-checkins at python.org Wed Jun 22 19:48:27 2011 From: python-checkins at python.org (r.david.murray) Date: Wed, 22 Jun 2011 19:48:27 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=231874=3A_detect_invalid_m?= =?utf8?q?ultipart_CTE_and_report_it_as_a_defect=2E?= Message-ID: http://hg.python.org/cpython/rev/5a2602939d5d changeset: 70925:5a2602939d5d user: R David Murray date: Wed Jun 22 13:47:53 2011 -0400 summary: #1874: detect invalid multipart CTE and report it as a defect. files: Lib/email/errors.py | 3 + Lib/email/feedparser.py | 5 ++ Lib/test/test_email/test_email.py | 45 +++++++++++++++++++ Misc/NEWS | 3 + 4 files changed, 56 insertions(+), 0 deletions(-) diff --git a/Lib/email/errors.py b/Lib/email/errors.py --- a/Lib/email/errors.py +++ b/Lib/email/errors.py @@ -55,3 +55,6 @@ class MultipartInvariantViolationDefect(MessageDefect): """A message claimed to be a multipart but no subparts were found.""" + +class InvalidMultipartContentTransferEncodingDefect(MessageDefect): + """An invalid content transfer encoding was set on the multipart itself.""" diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -300,6 +300,11 @@ lines.append(line) self._cur.set_payload(EMPTYSTRING.join(lines)) return + # Make sure a valid content type was specified per RFC 2045:6.4. + if (self._cur.get('content-transfer-encoding', '8bit').lower() + not in ('7bit', '8bit', 'binary')): + defect = errors.InvalidMultipartContentTransferEncodingDefect() + self.policy.handle_defect(self._cur, defect) # Create a line match predicate which matches the inter-part # boundary as well as the end-of-multipart boundary. Don't push # this onto the input stream until we've scanned past the diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -1809,6 +1809,51 @@ unless(isinstance(self.get_defects(msg)[1], errors.MultipartInvariantViolationDefect)) + multipart_msg = textwrap.dedent("""\ + Date: Wed, 14 Nov 2007 12:56:23 GMT + From: foo at bar.invalid + To: foo at bar.invalid + Subject: Content-Transfer-Encoding: base64 and multipart + MIME-Version: 1.0 + Content-Type: multipart/mixed; + boundary="===============3344438784458119861=="{} + + --===============3344438784458119861== + Content-Type: text/plain + + Test message + + --===============3344438784458119861== + Content-Type: application/octet-stream + Content-Transfer-Encoding: base64 + + YWJj + + --===============3344438784458119861==-- + """) + + def test_multipart_invalid_cte(self): + msg = email.message_from_string( + self.multipart_msg.format("\nContent-Transfer-Encoding: base64"), + policy = self.policy) + self.assertEqual(len(self.get_defects(msg)), 1) + self.assertIsInstance(self.get_defects(msg)[0], + errors.InvalidMultipartContentTransferEncodingDefect) + + def test_multipart_no_cte_no_defect(self): + msg = email.message_from_string( + self.multipart_msg.format(''), + policy = self.policy) + self.assertEqual(len(self.get_defects(msg)), 0) + + def test_multipart_valid_cte_no_defect(self): + for cte in ('7bit', '8bit', 'BINary'): + msg = email.message_from_string( + self.multipart_msg.format( + "\nContent-Transfer-Encoding: {}".format(cte)), + policy = self.policy) + self.assertEqual(len(self.get_defects(msg)), 0) + def test_invalid_content_type(self): eq = self.assertEqual neq = self.ndiffAssertEqual diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -196,6 +196,9 @@ Library ------- +- Issue #1874: email now detects and reports as a defect the presence of + any CTE other than 7bit, 8bit, or binary on a multipart. + - Issue #12383: Fix subprocess module with env={}: don't copy the environment variables, start with an empty environment. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 22 21:29:03 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 22 Jun 2011 21:29:03 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMzgz?= =?utf8?q?=3A_fix_test=5Fempty=5Fenv=28=29_of_subprocess_on_Mac_OS_X?= Message-ID: http://hg.python.org/cpython/rev/da3af4b131d7 changeset: 70926:da3af4b131d7 branch: 3.2 parent: 70923:8d46e84cd812 user: Victor Stinner date: Wed Jun 22 21:28:43 2011 +0200 summary: Issue #12383: fix test_empty_env() of subprocess on Mac OS X Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty environment. Fix also the test on the Py_ENABLE_SHARED config varible: test that the variable is present, don't check it's value. files: Lib/test/test_subprocess.py | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -339,7 +339,7 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") - @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') == 1, + @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None, 'the python library cannot be loaded ' 'with an empty environment') def test_empty_env(self): @@ -349,7 +349,11 @@ stdout=subprocess.PIPE, env={}) as p: stdout, stderr = p.communicate() - self.assertEqual(stdout.strip(), b"[]") + self.assertIn(stdout.strip(), + (b"[]", + # Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty + # environment + b"['__CF_USER_TEXT_ENCODING']")) def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 22 21:29:03 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 22 Jun 2011 21:29:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiAobWVyZ2UgMy4yKSBJc3N1ZSAjMTIzODM6IGZpeCB0ZXN0X2VtcHR5X2Vudigp?= =?utf8?q?_of_subprocess_on_Mac_OS_X?= Message-ID: http://hg.python.org/cpython/rev/29819072855a changeset: 70927:29819072855a parent: 70925:5a2602939d5d parent: 70926:da3af4b131d7 user: Victor Stinner date: Wed Jun 22 21:29:07 2011 +0200 summary: (merge 3.2) Issue #12383: fix test_empty_env() of subprocess on Mac OS X Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty environment. Fix also the test on the Py_ENABLE_SHARED config varible: test that the variable is present, don't check it's value. files: Lib/test/test_subprocess.py | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -390,7 +390,7 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") - @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') == 1, + @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None, 'the python library cannot be loaded ' 'with an empty environment') def test_empty_env(self): @@ -400,7 +400,11 @@ stdout=subprocess.PIPE, env={}) as p: stdout, stderr = p.communicate() - self.assertEqual(stdout.strip(), b"[]") + self.assertIn(stdout.strip(), + (b"[]", + # Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty + # environment + b"['__CF_USER_TEXT_ENCODING']")) def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 22 22:16:35 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 22 Jun 2011 22:16:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312363=3A_improve_s?= =?utf8?q?iginterrupt=28=29_tests?= Message-ID: http://hg.python.org/cpython/rev/aff0a7b0cb12 changeset: 70928:aff0a7b0cb12 user: Victor Stinner date: Wed Jun 22 22:15:51 2011 +0200 summary: Issue #12363: improve siginterrupt() tests Add a basic synchronization code between the child and the parent processes: the child writes "ready" to stdout. files: Lib/test/test_signal.py | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -333,6 +333,9 @@ def handler(signum, frame): pass + print("ready") + sys.stdout.flush() + signal.signal(signal.SIGALRM, handler) if interrupt is not None: signal.siginterrupt(signal.SIGALRM, interrupt) @@ -353,11 +356,15 @@ """ % (interrupt,) with spawn_python('-c', code) as process: try: + # wait until the child process is loaded and has started + first_line = process.stdout.readline() + stdout, stderr = process.communicate(timeout=3.0) except subprocess.TimeoutExpired: process.kill() return False else: + stdout = first_line + stdout exitcode = process.wait() if exitcode not in (2, 3): raise Exception("Child error (exit code %s): %s" -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 01:04:37 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 01:04:37 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMzgz?= =?utf8?q?=3A_skip_test=5Fempty=5Fenv=28=29_of_subprocess_on_Windows?= Message-ID: http://hg.python.org/cpython/rev/52c5f80122dd changeset: 70929:52c5f80122dd branch: 3.2 parent: 70926:da3af4b131d7 user: Victor Stinner date: Thu Jun 23 01:02:25 2011 +0200 summary: Issue #12383: skip test_empty_env() of subprocess on Windows Cannot test an empty environment on Windows: Windows requires at least the SYSTEMROOT environment variable to start Python. files: Lib/test/test_subprocess.py | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -339,6 +339,10 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") + # Windows requires at least the SYSTEMROOT environment variable to start + # Python + @unittest.skipIf(sys.platform == 'win32', + 'cannot test an empty env on Windows') @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None, 'the python library cannot be loaded ' 'with an empty environment') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 01:04:37 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 01:04:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiAobWVyZ2UgMy4yKSBJc3N1ZSAjMTIzODM6IHNraXAgdGVzdF9lbXB0eV9lbnYo?= =?utf8?q?=29_of_subprocess_on_Windows?= Message-ID: http://hg.python.org/cpython/rev/93cd98782f47 changeset: 70930:93cd98782f47 parent: 70928:aff0a7b0cb12 parent: 70929:52c5f80122dd user: Victor Stinner date: Thu Jun 23 01:02:50 2011 +0200 summary: (merge 3.2) Issue #12383: skip test_empty_env() of subprocess on Windows Cannot test an empty environment on Windows: Windows requires at least the SYSTEMROOT environment variable to start Python. files: Lib/test/test_subprocess.py | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -390,6 +390,10 @@ stdout, stderr = p.communicate() self.assertEqual(stdout, b"orange") + # Windows requires at least the SYSTEMROOT environment variable to start + # Python + @unittest.skipIf(sys.platform == 'win32', + 'cannot test an empty env on Windows') @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None, 'the python library cannot be loaded ' 'with an empty environment') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 02:03:05 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 23 Jun 2011 02:03:05 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzEyMzg5OiBmaXgg?= =?utf8?q?missing_space_at_sentence_end=2E?= Message-ID: http://hg.python.org/cpython/rev/a0ad25ca772b changeset: 70931:a0ad25ca772b branch: 2.7 parent: 70912:e72a2a60316f user: R David Murray date: Wed Jun 22 20:00:27 2011 -0400 summary: #12389: fix missing space at sentence end. files: Doc/library/urllib.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/urllib.rst b/Doc/library/urllib.rst --- a/Doc/library/urllib.rst +++ b/Doc/library/urllib.rst @@ -210,7 +210,7 @@ Replace special characters in *string* using the ``%xx`` escape. Letters, digits, and the characters ``'_.-'`` are never quoted. By default, this - function is intended for quoting the path section of the URL.The optional + function is intended for quoting the path section of the URL. The optional *safe* parameter specifies additional characters that should not be quoted --- its default value is ``'/'``. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 03:01:49 2011 From: python-checkins at python.org (r.david.murray) Date: Thu, 23 Jun 2011 03:01:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=2310354=3A_remove_last_pub?= =?utf8?q?lic_mentions_of_=27template=27_and_comment_as_private=2E?= Message-ID: http://hg.python.org/cpython/rev/eafe8c7f7049 changeset: 70932:eafe8c7f7049 parent: 70930:93cd98782f47 user: R David Murray date: Wed Jun 22 21:01:13 2011 -0400 summary: #10354: remove last public mentions of 'template' and comment as private. I didn't rename the variable because I can see no good reason to break backward compatibility just to put an underscore in the name. files: Doc/library/tempfile.rst | 2 +- Lib/tempfile.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -25,7 +25,7 @@ Also, all the user-callable functions now take additional arguments which allow direct control over the location and name of temporary files. It is -no longer necessary to use the global *tempdir* and *template* variables. +no longer necessary to use the global *tempdir* variable. To maintain backward compatibility, the argument order is somewhat odd; it is recommended to use keyword arguments for clarity. diff --git a/Lib/tempfile.py b/Lib/tempfile.py --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -10,8 +10,6 @@ TMP_MAX - maximum number of names that will be tried before giving up. - template - the default prefix for all temporary names. - You may change this to control the default prefix. tempdir - If this is set to a string before the first use of any routine from this module, it will be considered as another candidate location to store temporary files. @@ -74,6 +72,8 @@ else: TMP_MAX = 10000 +# Although it does not have an underscore for historical reasons, this +# variable is an internal implementation detail (see issue 10354). template = "tmp" # Internal routines. -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Thu Jun 23 05:11:00 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 23 Jun 2011 05:11:00 +0200 Subject: [Python-checkins] Daily reference leaks (eafe8c7f7049): sum=-23 Message-ID: results for eafe8c7f7049 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pydoc leaked [0, 0, -323] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/refloglkpJ9s', '-x'] From python-checkins at python.org Thu Jun 23 11:57:53 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 11:57:53 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzExMjIz?= =?utf8?q?=3A_skip_test=5Flock=5Facquire=5Finterruption=28=29_on_FreeBSD6?= Message-ID: http://hg.python.org/cpython/rev/07655b3dee4f changeset: 70933:07655b3dee4f branch: 3.2 parent: 70929:52c5f80122dd user: Victor Stinner date: Thu Jun 23 11:57:56 2011 +0200 summary: Issue #11223: skip test_lock_acquire_interruption() on FreeBSD6 Locks are implemented using a mutex and a condition variable of the pthread library on FreeBSD6. POSIX condition variables cannot be interrupted by signals (see pthread_cond_wait manual page). files: Lib/test/test_threadsignals.py | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -70,6 +70,11 @@ def alarm_interrupt(self, sig, frame): raise KeyboardInterrupt + # Issue #11223: Locks are implemented using a mutex and a condition + # variable of the pthread library on FreeBSD6. POSIX condition variables + # cannot be interrupted by signals (see pthread_cond_wait manual page). + @unittest.skipIf(sys.platform == 'freebsd6', + 'POSIX condition variables cannot be interrupted') def test_lock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 11:59:06 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 11:59:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28null_merge_3=2E2_for_issue_=2311223=29_python_3=2E3_has_a?= =?utf8?q?lready_a_better_fix?= Message-ID: http://hg.python.org/cpython/rev/3f18a03a2a1e changeset: 70934:3f18a03a2a1e parent: 70932:eafe8c7f7049 parent: 70933:07655b3dee4f user: Victor Stinner date: Thu Jun 23 11:59:15 2011 +0200 summary: (null merge 3.2 for issue #11223) python 3.3 has already a better fix files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 14:22:49 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 14:22:49 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzExMjIz?= =?utf8?q?=3A_skip_also_test=5Frlock=5Facquire=5Finterruption=28=29_on_Fre?= =?utf8?q?eBSD6?= Message-ID: http://hg.python.org/cpython/rev/e5183f16c49d changeset: 70935:e5183f16c49d branch: 3.2 parent: 70933:07655b3dee4f user: Victor Stinner date: Thu Jun 23 14:22:28 2011 +0200 summary: Issue #11223: skip also test_rlock_acquire_interruption() on FreeBSD6 files: Lib/test/test_threadsignals.py | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -14,6 +14,10 @@ process_pid = os.getpid() signalled_all=thread.allocate_lock() +# Issue #11223: Locks are implemented using a mutex and a condition variable of +# the pthread library on FreeBSD6. POSIX condition variables cannot be +# interrupted by signals (see pthread_cond_wait manual page). +USING_PTHREAD_COND = (sys.platform == 'freebsd6') def registerSignals(for_usr1, for_usr2, for_alrm): usr1 = signal.signal(signal.SIGUSR1, for_usr1) @@ -70,10 +74,7 @@ def alarm_interrupt(self, sig, frame): raise KeyboardInterrupt - # Issue #11223: Locks are implemented using a mutex and a condition - # variable of the pthread library on FreeBSD6. POSIX condition variables - # cannot be interrupted by signals (see pthread_cond_wait manual page). - @unittest.skipIf(sys.platform == 'freebsd6', + @unittest.skipIf(USING_PTHREAD_COND, 'POSIX condition variables cannot be interrupted') def test_lock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck @@ -96,6 +97,8 @@ finally: signal.signal(signal.SIGALRM, oldalrm) + @unittest.skipIf(USING_PTHREAD_COND, + 'POSIX condition variables cannot be interrupted') def test_rlock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 23 14:22:50 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 23 Jun 2011 14:22:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28null_merge_3=2E2_for_issue_=2311223=29_python_3=2E3_has_a?= =?utf8?q?lready_a_better_fix?= Message-ID: http://hg.python.org/cpython/rev/54fb77e0762c changeset: 70936:54fb77e0762c parent: 70934:3f18a03a2a1e parent: 70935:e5183f16c49d user: Victor Stinner date: Thu Jun 23 14:22:59 2011 +0200 summary: (null merge 3.2 for issue #11223) python 3.3 has already a better fix files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 03:27:50 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 24 Jun 2011 03:27:50 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzk5MjE6IGNsYXJp?= =?utf8?q?fy_os=2Epath=2Ejoin_joining_algorithm?= Message-ID: http://hg.python.org/cpython/rev/1e89444f4ebc changeset: 70937:1e89444f4ebc branch: 2.7 parent: 70931:a0ad25ca772b user: R David Murray date: Thu Jun 23 21:19:25 2011 -0400 summary: #9921: clarify os.path.join joining algorithm The new wording is based on the comments in the code, which match the actual behavior. files: Doc/library/os.path.rst | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -196,10 +196,11 @@ path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of *path1*, and optionally *path2*, etc., with exactly one - directory separator (``os.sep``) inserted between components, unless *path2* is - empty. Note that on Windows, since there is a current directory for each drive, - ``os.path.join("c:", "foo")`` represents a path relative to the current - directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. + directory separator (``os.sep``) following each non-empty part except the last. + (This means that an empty last part will result in a path that ends with a + separator.) Note that on Windows, since there is a current directory for + each drive, ``os.path.join("c:", "foo")`` represents a path relative to the + current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. .. function:: normcase(path) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 03:27:51 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 24 Jun 2011 03:27:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzk5MjE6IGNsYXJp?= =?utf8?q?fy_os=2Epath=2Ejoin_joining_algorithm?= Message-ID: http://hg.python.org/cpython/rev/f5f5b715be7e changeset: 70938:f5f5b715be7e branch: 3.2 parent: 70935:e5183f16c49d user: R David Murray date: Thu Jun 23 21:26:13 2011 -0400 summary: #9921: clarify os.path.join joining algorithm The new wording is based on the comments in the code, which match the actual behavior. files: Doc/library/os.path.rst | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -190,10 +190,11 @@ path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of *path1*, and optionally *path2*, etc., with exactly one - directory separator (``os.sep``) inserted between components, unless *path2* is - empty. Note that on Windows, since there is a current directory for each drive, - ``os.path.join("c:", "foo")`` represents a path relative to the current - directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. + directory separator (``os.sep``) following each non-empty part except the last. + (This means that an empty last part will result in a path that ends with a + separator.) Note that on Windows, since there is a current directory for + each drive, ``os.path.join("c:", "foo")`` represents a path relative to the + current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. .. function:: normcase(path) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 03:27:52 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 24 Jun 2011 03:27:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_=239921=3A_clarify_os=2Epath=2Ejoin_joining_algorithm?= Message-ID: http://hg.python.org/cpython/rev/b6759568b812 changeset: 70939:b6759568b812 parent: 70936:54fb77e0762c parent: 70938:f5f5b715be7e user: R David Murray date: Thu Jun 23 21:26:48 2011 -0400 summary: merge #9921: clarify os.path.join joining algorithm files: Doc/library/os.path.rst | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -190,10 +190,11 @@ path, all previous components (on Windows, including the previous drive letter, if there was one) are thrown away, and joining continues. The return value is the concatenation of *path1*, and optionally *path2*, etc., with exactly one - directory separator (``os.sep``) inserted between components, unless *path2* is - empty. Note that on Windows, since there is a current directory for each drive, - ``os.path.join("c:", "foo")`` represents a path relative to the current - directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. + directory separator (``os.sep``) following each non-empty part except the last. + (This means that an empty last part will result in a path that ends with a + separator.) Note that on Windows, since there is a current directory for + each drive, ``os.path.join("c:", "foo")`` represents a path relative to the + current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. .. function:: normcase(path) -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Fri Jun 24 05:08:33 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 24 Jun 2011 05:08:33 +0200 Subject: [Python-checkins] Daily reference leaks (b6759568b812): sum=-23 Message-ID: results for b6759568b812 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pyexpat leaked [0, -56, -267] references, sum=-323 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogjFyGXc', '-x'] From python-checkins at python.org Fri Jun 24 16:37:38 2011 From: python-checkins at python.org (benjamin.peterson) Date: Fri, 24 Jun 2011 16:37:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_give_the_names_of_missing_p?= =?utf8?q?ositional_or_keyword-only_arguments_=28closes_=2312356=29?= Message-ID: http://hg.python.org/cpython/rev/52744a5a9260 changeset: 70940:52744a5a9260 user: Benjamin Peterson date: Fri Jun 24 09:37:26 2011 -0500 summary: give the names of missing positional or keyword-only arguments (closes #12356) files: Lib/inspect.py | 41 +++++-- Lib/test/test_extcall.py | 113 +++++++++----------- Misc/NEWS | 4 + Python/ceval.c | 141 ++++++++++++++++++++++---- 4 files changed, 202 insertions(+), 97 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -918,10 +918,24 @@ specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) return '(' + ', '.join(specs) + ')' -def _positional_error(f_name, args, kwonly, varargs, defcount, given, values): +def _missing_arguments(f_name, argnames, pos, values): + names = [repr(name) for name in argnames if name not in values] + missing = len(names) + if missing == 1: + s = names[0] + elif missing == 2: + s = "{} and {}".format(*names) + else: + tail = ", {} and {}".format(names[-2:]) + del names[-2:] + s = ", ".join(names) + tail + raise TypeError("%s() missing %i required %s argument%s: %s" % + (f_name, missing, + "positional" if pos else "keyword-only", + "" if missing == 1 else "s", s)) + +def _too_many(f_name, args, kwonly, varargs, defcount, given, values): atleast = len(args) - defcount - if given is None: - given = len([arg for arg in args if arg in values]) kwonly_given = len([arg for arg in kwonly if arg in values]) if varargs: plural = atleast != 1 @@ -980,22 +994,25 @@ (f_name, kw)) arg2value[kw] = value if num_pos > num_args and not varargs: - _positional_error(f_name, args, kwonlyargs, varargs, num_defaults, - num_pos, arg2value) + _too_many(f_name, args, kwonlyargs, varargs, num_defaults, + num_pos, arg2value) if num_pos < num_args: - for arg in args[:num_args - num_defaults]: + req = args[:num_args - num_defaults] + for arg in req: if arg not in arg2value: - _positional_error(f_name, args, kwonlyargs, varargs, - num_defaults, None, arg2value) + _missing_arguments(f_name, req, True, arg2value) for i, arg in enumerate(args[num_args - num_defaults:]): if arg not in arg2value: arg2value[arg] = defaults[i] + missing = 0 for kwarg in kwonlyargs: if kwarg not in arg2value: - if kwarg not in kwonlydefaults: - raise TypeError("%s() requires keyword-only argument %r" % - (f_name, kwarg)) - arg2value[kwarg] = kwonlydefaults[kwarg] + if kwarg in kwonlydefaults: + arg2value[kwarg] = kwonlydefaults[kwarg] + else: + missing += 1 + if missing: + _missing_arguments(f_name, kwonlyargs, False, arg2value) return arg2value # -------------------------------------------------- stack frame extraction diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -66,17 +66,17 @@ >>> g() Traceback (most recent call last): ... - TypeError: g() takes at least 1 positional argument but 0 were given + TypeError: g() missing 1 required positional argument: 'x' >>> g(*()) Traceback (most recent call last): ... - TypeError: g() takes at least 1 positional argument but 0 were given + TypeError: g() missing 1 required positional argument: 'x' >>> g(*(), **{}) Traceback (most recent call last): ... - TypeError: g() takes at least 1 positional argument but 0 were given + TypeError: g() missing 1 required positional argument: 'x' >>> g(1) 1 () {} @@ -263,91 +263,80 @@ >>> f(**x) 1 2 -Some additional tests about positional argument errors: +Too many arguments: - >>> def f(a, b): - ... pass - >>> f(b=1) + >>> def f(): pass + >>> f(1) Traceback (most recent call last): ... - TypeError: f() takes 2 positional arguments but 1 was given - - >>> def f(a): - ... pass - >>> f(6, a=4, *(1, 2, 3)) + TypeError: f() takes 0 positional arguments but 1 was given + >>> def f(a): pass + >>> f(1, 2) Traceback (most recent call last): ... - TypeError: f() got multiple values for argument 'a' - >>> def f(a, *, kw): - ... pass - >>> f(6, 4, kw=4) + TypeError: f() takes 1 positional argument but 2 were given + >>> def f(a, b=1): pass + >>> f(1, 2, 3) Traceback (most recent call last): ... - TypeError: f() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given + TypeError: f() takes from 1 to 2 positional arguments but 3 were given + >>> def f(*, kw): pass + >>> f(1, kw=3) + Traceback (most recent call last): + ... + TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given + >>> def f(*, kw, b): pass + >>> f(1, 2, 3, b=3, kw=3) + Traceback (most recent call last): + ... + TypeError: f() takes 0 positional arguments but 3 positional arguments (and 2 keyword-only arguments) were given + >>> def f(a, b=2, *, kw): pass + >>> f(2, 3, 4, kw=4) + Traceback (most recent call last): + ... + TypeError: f() takes from 1 to 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given - >>> def f(a): - ... pass +Too few and missing arguments: + + >>> def f(a): pass >>> f() Traceback (most recent call last): ... - TypeError: f() takes 1 positional argument but 0 were given - - >>> def f(a, b): - ... pass - >>> f(1) - Traceback (most recent call last): - ... - TypeError: f() takes 2 positional arguments but 1 was given - - >>> def f(a, *b): - ... pass + TypeError: f() missing 1 required positional argument: 'a' + >>> def f(a, b): pass >>> f() Traceback (most recent call last): ... - TypeError: f() takes at least 1 positional argument but 0 were given - - >>> def f(a, *, kw=4): - ... pass - >>> f(kw=4) - Traceback (most recent call last): - ... - TypeError: f() takes 1 positional argument but 0 positional arguments (and 1 keyword-only argument) were given - - >>> def f(a, b=2): - ... pass + TypeError: f() missing 2 required positional arguments: 'a' and 'b' + >>> def f(a, b, c): pass >>> f() Traceback (most recent call last): ... - TypeError: f() takes from 1 to 2 positional arguments but 0 were given - - >>> def f(a, *b): - ... pass + TypeError: f() missing 3 required positional arguments: 'a', 'b', and 'c' + >>> def f(a, b, c, d, e): pass >>> f() Traceback (most recent call last): ... - TypeError: f() takes at least 1 positional argument but 0 were given - - >>> def f(*, kw): - ... pass - >>> f(3, kw=4) + TypeError: f() missing 5 required positional arguments: 'a', 'b', 'c', 'd', and 'e' + >>> def f(a, b=4, c=5, d=5): pass + >>> f(c=12, b=9) Traceback (most recent call last): ... - TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given + TypeError: f() missing 1 required positional argument: 'a' - >>> def f(a, c=3, *b, kw): - ... pass +Same with keyword only args: + + >>> def f(*, w): pass >>> f() Traceback (most recent call last): - ... - TypeError: f() takes at least 1 positional argument but 0 were given - >>> f(kw=3) + ... + TypeError: f() missing 1 required keyword-only argument: 'w' + >>> def f(*, a, b, c, d, e): pass + >>> f() Traceback (most recent call last): - ... - TypeError: f() takes at least 1 positional argument but 0 positional arguments (and 1 keyword-only argument) were given - >>> f(kw=3, c=4) - Traceback (most recent call last): - ... - TypeError: f() takes at least 1 positional argument but 1 positional argument (and 1 keyword-only argument) were given + ... + TypeError: f() missing 5 required keyword-only arguments: 'a', 'b', 'c', 'd', and 'e' + """ import sys diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #12356: When required positional or keyword-only arguments are not + given, produce a informative error message which includes the name(s) of the + missing arguments. + - Issue #12370: Fix super with not arguments when __class__ is overriden in the class body. diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3046,28 +3046,118 @@ } static void -positional_argument_error(PyCodeObject *co, int given, int defcount, PyObject **fastlocals) +format_missing(const char *kind, PyCodeObject *co, PyObject *names) +{ + int err; + Py_ssize_t len = PyList_GET_SIZE(names); + PyObject *name_str, *comma, *tail, *tmp; + + assert(PyList_CheckExact(names)); + assert(len >= 1); + /* Deal with the joys of natural language. */ + switch (len) { + case 1: + name_str = PyList_GET_ITEM(names, 0); + Py_INCREF(name_str); + break; + case 2: + name_str = PyUnicode_FromFormat("%U and %U", + PyList_GET_ITEM(names, len - 2), + PyList_GET_ITEM(names, len - 1)); + break; + default: + tail = PyUnicode_FromFormat(", %U, and %U", + PyList_GET_ITEM(names, len - 2), + PyList_GET_ITEM(names, len - 1)); + /* Chop off the last two objects in the list. This shouldn't actually + fail, but we can't be too careful. */ + err = PyList_SetSlice(names, len - 2, len, NULL); + if (err == -1) { + Py_DECREF(tail); + return; + } + /* Stitch everything up into a nice comma-separated list. */ + comma = PyUnicode_FromString(", "); + if (comma == NULL) { + Py_DECREF(tail); + return; + } + tmp = PyUnicode_Join(comma, names); + Py_DECREF(comma); + if (tmp == NULL) { + Py_DECREF(tail); + return; + } + name_str = PyUnicode_Concat(tmp, tail); + Py_DECREF(tmp); + Py_DECREF(tail); + break; + } + if (name_str == NULL) + return; + PyErr_Format(PyExc_TypeError, + "%U() missing %i required %s argument%s: %U", + co->co_name, + len, + kind, + len == 1 ? "" : "s", + name_str); + Py_DECREF(name_str); +} + +static void +missing_arguments(PyCodeObject *co, int missing, int defcount, + PyObject **fastlocals) +{ + int i, j = 0; + int start, end; + int positional = defcount != -1; + const char *kind = positional ? "positional" : "keyword-only"; + PyObject *missing_names; + + /* Compute the names of the arguments that are missing. */ + missing_names = PyList_New(missing); + if (missing_names == NULL) + return; + if (positional) { + start = 0; + end = co->co_argcount - defcount; + } + else { + start = co->co_argcount; + end = start + co->co_kwonlyargcount; + } + for (i = start; i < end; i++) { + if (GETLOCAL(i) == NULL) { + PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i); + PyObject *name = PyObject_Repr(raw); + if (name == NULL) { + Py_DECREF(missing_names); + return; + } + PyList_SET_ITEM(missing_names, j++, name); + } + } + assert(j == missing); + format_missing(kind, co, missing_names); + Py_DECREF(missing_names); +} + +static void +too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals) { int plural; int kwonly_given = 0; - int atleast = co->co_argcount - defcount; int i; PyObject *sig, *kwonly_sig; - if (given == -1) { - given = 0; - for (i = 0; i < co->co_argcount; i++) - if (GETLOCAL(i)) - given++; - } + assert((co->co_flags & CO_VARARGS) == 0); + /* Count missing keyword-only args. */ for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++) - if (GETLOCAL(i)) + if (GETLOCAL(i) != NULL) kwonly_given++; - if (co->co_flags & CO_VARARGS) { - plural = atleast != 1; - sig = PyUnicode_FromFormat("at least %d", atleast); - } - else if (defcount) { + if (defcount) { + int atleast = co->co_argcount - defcount; plural = 1; sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount); } @@ -3089,6 +3179,7 @@ else { /* This will not fail. */ kwonly_sig = PyUnicode_FromString(""); + assert(kwonly_sig != NULL); } PyErr_Format(PyExc_TypeError, "%U() takes %U positional argument%s but %d%U %s given", @@ -3217,16 +3308,18 @@ SETLOCAL(j, value); } if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { - positional_argument_error(co, argcount, defcount, fastlocals); + too_many_positional(co, argcount, defcount, fastlocals); goto fail; } if (argcount < co->co_argcount) { int m = co->co_argcount - defcount; - for (i = argcount; i < m; i++) { - if (GETLOCAL(i) == NULL) { - positional_argument_error(co, -1, defcount, fastlocals); - goto fail; - } + int missing = 0; + for (i = argcount; i < m; i++) + if (GETLOCAL(i) == NULL) + missing++; + if (missing) { + missing_arguments(co, missing, defcount, fastlocals); + goto fail; } if (n > m) i = n - m; @@ -3241,6 +3334,7 @@ } } if (co->co_kwonlyargcount > 0) { + int missing = 0; for (i = co->co_argcount; i < total_args; i++) { PyObject *name; if (GETLOCAL(i) != NULL) @@ -3254,9 +3348,10 @@ continue; } } - PyErr_Format(PyExc_TypeError, - "%U() requires keyword-only argument '%S'", - co->co_name, name); + missing++; + } + if (missing) { + missing_arguments(co, missing, -1, fastlocals); goto fail; } } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 19:28:34 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 24 Jun 2011 19:28:34 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzEwMjA2OiBhZGQg?= =?utf8?q?test_for_previously_fixed_bug=2E?= Message-ID: http://hg.python.org/cpython/rev/2a4764376c51 changeset: 70941:2a4764376c51 branch: 3.2 parent: 70938:f5f5b715be7e user: R David Murray date: Fri Jun 24 13:26:31 2011 -0400 summary: #10206: add test for previously fixed bug. Patch by Francisco Mart?n Brugu?. files: Lib/test/test_cmd_line.py | 7 +++++++ Misc/ACKS | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -265,6 +265,13 @@ "print(repr(input()))", b"'abc'") + def test_unmached_quote(self): + # Issue #10206: python program starting with unmatched quote + # spewed spaces to stdout + rc, out, err = assert_python_failure('-c', "'") + self.assertRegex(err.decode('ascii', 'ignore'), 'SyntaxError') + self.assertEqual(b'', out) + def test_main(): test.support.run_unittest(CmdLineTest) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -122,6 +122,7 @@ Gary S. Brown Oleg Broytmann Dave Brueck +Francisco Mart?n Brugu? Stan Bubrouski Erik de Bueger Dick Bulterman -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 19:28:35 2011 From: python-checkins at python.org (r.david.murray) Date: Fri, 24 Jun 2011 19:28:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_=2310206=3A_add_test_for_previously_fixed_bug=2E?= Message-ID: http://hg.python.org/cpython/rev/5ec95f46bac5 changeset: 70942:5ec95f46bac5 parent: 70940:52744a5a9260 parent: 70941:2a4764376c51 user: R David Murray date: Fri Jun 24 13:28:08 2011 -0400 summary: Merge #10206: add test for previously fixed bug. files: Lib/test/test_cmd_line.py | 7 +++++++ Misc/ACKS | 1 + 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -259,6 +259,13 @@ "print(repr(input()))", b"'abc'") + def test_unmached_quote(self): + # Issue #10206: python program starting with unmatched quote + # spewed spaces to stdout + rc, out, err = assert_python_failure('-c', "'") + self.assertRegex(err.decode('ascii', 'ignore'), 'SyntaxError') + self.assertEqual(b'', out) + def test_main(): test.support.run_unittest(CmdLineTest) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -129,6 +129,7 @@ Titus Brown Oleg Broytmann Dave Brueck +Francisco Mart?n Brugu? Stan Bubrouski Erik de Bueger Dick Bulterman -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Fri Jun 24 20:53:28 2011 From: python-checkins at python.org (victor.stinner) Date: Fri, 24 Jun 2011 20:53:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312392=3A_fix_threa?= =?utf8?q?d_initialization_on_FreeBSD_6?= Message-ID: http://hg.python.org/cpython/rev/024827a9db64 changeset: 70943:024827a9db64 user: Victor Stinner date: Fri Jun 24 20:52:27 2011 +0200 summary: Issue #12392: fix thread initialization on FreeBSD 6 On FreeBSD6, pthread_kill() doesn't work on the main thread before the creation of the first thread. Create therefore a dummy thread (no-op) a startup to initialize the pthread library. Add also a test for this use case, test written by Charles-Fran?ois Natali. files: Lib/test/test_signal.py | 25 +++++++++++++++++++++++++ Python/thread_pthread.h | 5 ++++- 2 files changed, 29 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -295,6 +295,31 @@ self.check_signum(signum1, signum2) + @unittest.skipUnless(hasattr(signal, 'pthread_kill'), + 'need signal.pthread_kill()') + def test_pthread_kill_main_thread(self): + # Test that a signal can be sent to the main thread with pthread_kill() + # before any other thread has been created (see issue #12392). + code = """if True: + import threading + import signal + import sys + + def handler(signum, frame): + sys.exit(3) + + signal.signal(signal.SIGUSR1, handler) + signal.pthread_kill(threading.get_ident(), signal.SIGUSR1) + sys.exit(1) + """ + + with spawn_python('-c', code) as process: + stdout, stderr = process.communicate() + exitcode = process.wait() + if exitcode != 3: + raise Exception("Child error (exit code %s): %s" % + (exitcode, stdout)) + def setUp(self): import fcntl diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -144,7 +144,10 @@ * Initialization. */ -#ifdef _HAVE_BSDI +/* On FreeBSD6, pthread_kill() doesn't work on the main thread before + the creation of the first thread */ +#if defined(_HAVE_BSDI) \ + || (defined(__FreeBSD__) && __FreeBSD_version < 700000) static void _noop(void) { -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Sat Jun 25 05:15:29 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 25 Jun 2011 05:15:29 +0200 Subject: [Python-checkins] Daily reference leaks (024827a9db64): sum=298 Message-ID: results for 024827a9db64 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_urllib2net leaked [-2, 0, 0] references, sum=-2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogC4bLWn', '-x'] From python-checkins at python.org Sat Jun 25 10:14:17 2011 From: python-checkins at python.org (ross.lagerwall) Date: Sat, 25 Jun 2011 10:14:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Issue_12404=3A_?= =?utf8?q?Remove_C89_incompatible_code_from_mmap_module=2E?= Message-ID: http://hg.python.org/cpython/rev/c72dafb14c49 changeset: 70944:c72dafb14c49 branch: 2.7 parent: 70937:1e89444f4ebc user: Ross Lagerwall date: Sat Jun 25 09:55:10 2011 +0200 summary: Issue 12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. files: Misc/NEWS | 3 +++ Modules/mmapmodule.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Library ------- +- Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira + Kitada. + - Issue #11700: mailbox proxy object close methods can now be called multiple times without error, and _ProxyFile now closes the wrapped file. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1188,12 +1188,13 @@ # endif if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { + off_t calc_size; if (offset >= st.st_size) { PyErr_SetString(PyExc_ValueError, "mmap offset is greater than file size"); return NULL; } - off_t calc_size = st.st_size - offset; + calc_size = st.st_size - offset; map_size = calc_size; if (map_size != calc_size) { PyErr_SetString(PyExc_ValueError, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 10:14:18 2011 From: python-checkins at python.org (ross.lagerwall) Date: Sat, 25 Jun 2011 10:14:18 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Issue_12404=3A_?= =?utf8?q?Remove_C89_incompatible_code_from_mmap_module=2E?= Message-ID: http://hg.python.org/cpython/rev/567236a7122c changeset: 70945:567236a7122c branch: 3.2 parent: 70941:2a4764376c51 user: Ross Lagerwall date: Sat Jun 25 10:02:37 2011 +0200 summary: Issue 12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. files: Misc/NEWS | 3 +++ Modules/mmapmodule.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira + Kitada. + - Issue #12383: Fix subprocess module with env={}: don't copy the environment variables, start with an empty environment. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1140,12 +1140,13 @@ # endif if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { + off_t calc_size; if (offset >= st.st_size) { PyErr_SetString(PyExc_ValueError, "mmap offset is greater than file size"); return NULL; } - off_t calc_size = st.st_size - offset; + calc_size = st.st_size - offset; map_size = calc_size; if (map_size != calc_size) { PyErr_SetString(PyExc_ValueError, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 10:14:19 2011 From: python-checkins at python.org (ross.lagerwall) Date: Sat, 25 Jun 2011 10:14:19 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_with_3=2E2_=28Issue_=2312404=29=2E?= Message-ID: http://hg.python.org/cpython/rev/04182fa5255b changeset: 70946:04182fa5255b parent: 70943:024827a9db64 parent: 70945:567236a7122c user: Ross Lagerwall date: Sat Jun 25 10:11:44 2011 +0200 summary: Merge with 3.2 (Issue #12404). files: Misc/NEWS | 3 +++ Modules/mmapmodule.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,9 @@ Library ------- +- Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira + Kitada. + - Issue #1874: email now detects and reports as a defect the presence of any CTE other than 7bit, 8bit, or binary on a multipart. diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -1162,12 +1162,13 @@ # endif if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { + off_t calc_size; if (offset >= st.st_size) { PyErr_SetString(PyExc_ValueError, "mmap offset is greater than file size"); return NULL; } - off_t calc_size = st.st_size - offset; + calc_size = st.st_size - offset; map_size = calc_size; if (map_size != calc_size) { PyErr_SetString(PyExc_ValueError, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:00:19 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 11:00:19 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMTY0?= =?utf8?q?=3A_Document_=28in_docstring=29_that_str=2Etranslate_accepts_Non?= =?utf8?q?e_for_the?= Message-ID: http://hg.python.org/cpython/rev/60b3a5615c4e changeset: 70947:60b3a5615c4e branch: 2.7 parent: 70944:c72dafb14c49 user: Mark Dickinson date: Sat Jun 25 11:00:12 2011 +0200 summary: Issue #12164: Document (in docstring) that str.translate accepts None for the first argument. files: Objects/stringobject.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Objects/stringobject.c b/Objects/stringobject.c --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -2173,7 +2173,9 @@ Return a copy of the string S, where all characters occurring\n\ in the optional argument deletechars are removed, and the\n\ remaining characters have been mapped through the given\n\ -translation table, which must be a string of length 256."); +translation table, which must be a string of length 256 or None.\n\ +If the table argument is None, no translation is applied and\n\ +the operation simply removes the characters in deletechars."); static PyObject * string_translate(PyStringObject *self, PyObject *args) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:24:46 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:24:46 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Code_simplifica?= =?utf8?q?tion_suggested_by_Sven_Marnach=2E?= Message-ID: http://hg.python.org/cpython/rev/4970fa3c4a0b changeset: 70948:4970fa3c4a0b branch: 2.7 user: Raymond Hettinger date: Sat Jun 25 11:24:35 2011 +0200 summary: Code simplification suggested by Sven Marnach. files: Lib/random.py | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/random.py b/Lib/random.py --- a/Lib/random.py +++ b/Lib/random.py @@ -427,11 +427,9 @@ # lambd: rate lambd = 1/mean # ('lambda' is a Python reserved word) - random = self.random - u = random() - while u <= 1e-7: - u = random() - return -_log(u)/lambd + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd ## -------------------- von Mises distribution -------------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:32:02 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:32:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Code_simplifica?= =?utf8?q?tion_suggested_by_Sven_Marnach=2E?= Message-ID: http://hg.python.org/cpython/rev/9216e0a5d950 changeset: 70949:9216e0a5d950 branch: 3.2 parent: 70945:567236a7122c user: Raymond Hettinger date: Sat Jun 25 11:30:53 2011 +0200 summary: Code simplification suggested by Sven Marnach. files: Lib/random.py | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/random.py b/Lib/random.py --- a/Lib/random.py +++ b/Lib/random.py @@ -402,11 +402,9 @@ # lambd: rate lambd = 1/mean # ('lambda' is a Python reserved word) - random = self.random - u = random() - while u <= 1e-7: - u = random() - return -_log(u)/lambd + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd ## -------------------- von Mises distribution -------------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:32:02 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:32:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Code_simplification_suggested_by_Sven_Marnach=2E?= Message-ID: http://hg.python.org/cpython/rev/67ea5cebca1c changeset: 70950:67ea5cebca1c parent: 70946:04182fa5255b parent: 70949:9216e0a5d950 user: Raymond Hettinger date: Sat Jun 25 11:31:46 2011 +0200 summary: Code simplification suggested by Sven Marnach. files: Lib/random.py | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/random.py b/Lib/random.py --- a/Lib/random.py +++ b/Lib/random.py @@ -402,11 +402,9 @@ # lambd: rate lambd = 1/mean # ('lambda' is a Python reserved word) - random = self.random - u = random() - while u <= 1e-7: - u = random() - return -_log(u)/lambd + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd ## -------------------- von Mises distribution -------------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:38:30 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 11:38:30 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzEyMzQxOiBhZGQg?= =?utf8?q?coverage_files/dirs_to_=2Ehgignore=2E_Patch_by_Sandro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/eaaa073a9a42 changeset: 70951:eaaa073a9a42 branch: 3.2 parent: 70949:9216e0a5d950 user: Ezio Melotti date: Sat Jun 25 12:36:38 2011 +0300 summary: #12341: add coverage files/dirs to .hgignore. Patch by Sandro Tosi. files: .bzrignore | 3 +++ .gitignore | 3 +++ .hgignore | 3 +++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -37,3 +37,6 @@ Lib/lib2to3/Grammar*.pickle Lib/lib2to3/PatternGrammar*.pickle __pycache__ +.coverage +coverage/* +htmlcov/* diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ python python-gdb.py tags +.coverage +coverage/ +htmlcov/ diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -65,3 +65,6 @@ PCbuild/Win32-temp-* __pycache__ Modules/_testembed +.coverage +coverage/ +htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:38:31 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 11:38:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_with_3=2E2=2E?= Message-ID: http://hg.python.org/cpython/rev/ea43a99d7536 changeset: 70952:ea43a99d7536 parent: 70950:67ea5cebca1c parent: 70951:eaaa073a9a42 user: Ezio Melotti date: Sat Jun 25 12:38:16 2011 +0300 summary: Merge with 3.2. files: .bzrignore | 3 +++ .gitignore | 3 +++ .hgignore | 3 +++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -37,3 +37,6 @@ Lib/lib2to3/Grammar*.pickle Lib/lib2to3/PatternGrammar*.pickle __pycache__ +.coverage +coverage/* +htmlcov/* diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ python python-gdb.py tags +.coverage +coverage/ +htmlcov/ diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -70,3 +70,6 @@ PCbuild/x64-temp-* __pycache__ Modules/_testembed +.coverage +coverage/ +htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:02 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_typo_=28rep?= =?utf8?q?orted_by_Hiro_Ashiya=29=2E?= Message-ID: http://hg.python.org/cpython/rev/23f9cfa1f597 changeset: 70953:23f9cfa1f597 branch: 3.2 parent: 70949:9216e0a5d950 user: Raymond Hettinger date: Sat Jun 25 11:39:00 2011 +0200 summary: Fix typo (reported by Hiro Ashiya). files: Doc/library/collections.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -821,10 +821,10 @@ >>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'acdeb' >>> d.move_to_end('b', last=False) - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'bacde' .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:03 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Fix_typo_=28reported_by_Hiro_Ashiya=29=2E?= Message-ID: http://hg.python.org/cpython/rev/2db99429beb4 changeset: 70954:2db99429beb4 parent: 70950:67ea5cebca1c parent: 70953:23f9cfa1f597 user: Raymond Hettinger date: Sat Jun 25 11:39:42 2011 +0200 summary: Fix typo (reported by Hiro Ashiya). files: Doc/library/collections.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -900,10 +900,10 @@ >>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'acdeb' >>> d.move_to_end('b', last=False) - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'bacde' .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:04 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge?= Message-ID: http://hg.python.org/cpython/rev/ce6c2ef8c5c5 changeset: 70955:ce6c2ef8c5c5 parent: 70952:ea43a99d7536 parent: 70954:2db99429beb4 user: Raymond Hettinger date: Sat Jun 25 11:48:54 2011 +0200 summary: merge files: Doc/library/collections.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -900,10 +900,10 @@ >>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'acdeb' >>> d.move_to_end('b', last=False) - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'bacde' .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:04 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge?= Message-ID: http://hg.python.org/cpython/rev/bd15651f4328 changeset: 70956:bd15651f4328 parent: 70954:2db99429beb4 parent: 70952:ea43a99d7536 user: Raymond Hettinger date: Sat Jun 25 11:40:20 2011 +0200 summary: merge files: .bzrignore | 3 +++ .gitignore | 3 +++ .hgignore | 3 +++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -37,3 +37,6 @@ Lib/lib2to3/Grammar*.pickle Lib/lib2to3/PatternGrammar*.pickle __pycache__ +.coverage +coverage/* +htmlcov/* diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ python python-gdb.py tags +.coverage +coverage/ +htmlcov/ diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -70,3 +70,6 @@ PCbuild/x64-temp-* __pycache__ Modules/_testembed +.coverage +coverage/ +htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:05 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:05 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_merge?= Message-ID: http://hg.python.org/cpython/rev/96ce58d2d6bd changeset: 70957:96ce58d2d6bd branch: 3.2 parent: 70951:eaaa073a9a42 parent: 70953:23f9cfa1f597 user: Raymond Hettinger date: Sat Jun 25 11:50:00 2011 +0200 summary: merge files: Doc/library/collections.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -821,10 +821,10 @@ >>> d = OrderedDict.fromkeys('abcde') >>> d.move_to_end('b') - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'acdeb' >>> d.move_to_end('b', last=False) - >>> ''.join(d.keys) + >>> ''.join(d.keys()) 'bacde' .. versionadded:: 3.2 -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 11:53:06 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 11:53:06 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge?= Message-ID: http://hg.python.org/cpython/rev/4ac3a72d969f changeset: 70958:4ac3a72d969f parent: 70955:ce6c2ef8c5c5 parent: 70956:bd15651f4328 user: Raymond Hettinger date: Sat Jun 25 11:52:37 2011 +0200 summary: merge files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:02:58 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 12:02:58 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMjI4?= =?utf8?q?=3A_Fix_exchanged_flag_descriptions_in_stat=2Erst=2E__Thanks_San?= =?utf8?q?dro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/d912dfb7ab7a changeset: 70959:d912dfb7ab7a branch: 2.7 parent: 70947:60b3a5615c4e user: Mark Dickinson date: Sat Jun 25 12:01:06 2011 +0200 summary: Issue #12228: Fix exchanged flag descriptions in stat.rst. Thanks Sandro Tosi. files: Doc/library/stat.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -304,11 +304,11 @@ The file may only be appended to. -.. data:: UF_OPAQUE +.. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_NOUNLINK +.. data:: UF_OPAQUE The directory is opaque when viewed through a union stack. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:02:59 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 12:02:59 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge?= Message-ID: http://hg.python.org/cpython/rev/183621c377ef changeset: 70960:183621c377ef branch: 2.7 parent: 70959:d912dfb7ab7a parent: 70948:4970fa3c4a0b user: Mark Dickinson date: Sat Jun 25 12:02:53 2011 +0200 summary: merge files: Lib/random.py | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/random.py b/Lib/random.py --- a/Lib/random.py +++ b/Lib/random.py @@ -427,11 +427,9 @@ # lambd: rate lambd = 1/mean # ('lambda' is a Python reserved word) - random = self.random - u = random() - while u <= 1e-7: - u = random() - return -_log(u)/lambd + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd ## -------------------- von Mises distribution -------------------- -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:05:34 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 12:05:34 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4xKTogSXNzdWUgIzEyMjI4?= =?utf8?q?=3A_Fix_exchanged_flag_descriptions_in_stat=2Erst=2E__Thanks_San?= =?utf8?q?dro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/03c8de42c206 changeset: 70961:03c8de42c206 branch: 3.1 parent: 70876:4211ace1ff5d user: Mark Dickinson date: Sat Jun 25 12:03:33 2011 +0200 summary: Issue #12228: Fix exchanged flag descriptions in stat.rst. Thanks Sandro Tosi. files: Doc/library/stat.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -304,11 +304,11 @@ The file may only be appended to. -.. data:: UF_OPAQUE +.. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_NOUNLINK +.. data:: UF_OPAQUE The directory is opaque when viewed through a union stack. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:05:35 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 12:05:35 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_Merge_=2312228?= Message-ID: http://hg.python.org/cpython/rev/4a3e528b6b11 changeset: 70962:4a3e528b6b11 branch: 3.2 parent: 70957:96ce58d2d6bd parent: 70961:03c8de42c206 user: Mark Dickinson date: Sat Jun 25 12:04:08 2011 +0200 summary: Merge #12228 files: Doc/library/stat.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -307,11 +307,11 @@ The file may only be appended to. -.. data:: UF_OPAQUE +.. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_NOUNLINK +.. data:: UF_OPAQUE The directory is opaque when viewed through a union stack. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:05:35 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 12:05:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_=2312228?= Message-ID: http://hg.python.org/cpython/rev/6c6ee4eb27f8 changeset: 70963:6c6ee4eb27f8 parent: 70958:4ac3a72d969f parent: 70962:4a3e528b6b11 user: Mark Dickinson date: Sat Jun 25 12:04:45 2011 +0200 summary: Merge #12228 files: Doc/library/stat.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -307,11 +307,11 @@ The file may only be appended to. -.. data:: UF_OPAQUE +.. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_NOUNLINK +.. data:: UF_OPAQUE The directory is opaque when viewed through a union stack. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:15:08 2011 From: python-checkins at python.org (ross.lagerwall) Date: Sat, 25 Jun 2011 12:15:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312303=3A_Add_sigwa?= =?utf8?q?itinfo=28=29_and_sigtimedwait=28=29_to_the_signal_module=2E?= Message-ID: http://hg.python.org/cpython/rev/1137f7021b95 changeset: 70964:1137f7021b95 user: Ross Lagerwall date: Sat Jun 25 12:13:40 2011 +0200 summary: Issue #12303: Add sigwaitinfo() and sigtimedwait() to the signal module. files: Doc/library/signal.rst | 45 +++++++- Doc/whatsnew/3.3.rst | 4 + Lib/test/test_signal.py | 99 +++++++++++++++-- Misc/NEWS | 2 + Modules/signalmodule.c | 154 +++++++++++++++++++++++++++- configure | 4 +- configure.in | 4 +- pyconfig.h.in | 6 + 8 files changed, 295 insertions(+), 23 deletions(-) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -179,7 +179,8 @@ will then be called. Returns nothing. Not on Windows. (See the Unix man page :manpage:`signal(2)`.) - See also :func:`sigwait` and :func:`sigpending`. + See also :func:`sigwait`, :func:`sigwaitinfo`, :func:`sigtimedwait` and + :func:`sigpending`. .. function:: pthread_kill(thread_id, signum) @@ -334,7 +335,47 @@ Availability: Unix (see the man page :manpage:`sigwait(3)` for further information). - See also :func:`pause`, :func:`pthread_sigmask` and :func:`sigpending`. + See also :func:`pause`, :func:`pthread_sigmask`, :func:`sigpending`, + :func:`sigwaitinfo` and :func:`sigtimedwait`. + + .. versionadded:: 3.3 + + +.. function:: sigwaitinfo(sigset) + + Suspend execution of the calling thread until the delivery of one of the + signals specified in the signal set *sigset*. The function accepts the + signal and removes it from the pending list of signals. If one of the + signals in *sigset* is already pending for the calling thread, the function + will return immediately with information about that signal. The signal + handler is not called for the delivered signal. The function raises an + :exc:`OSError` with error number set to :const:`errno.EINTR` if it is + interrupted by a signal that is not in *sigset*. + + The return value is an object representing the data contained in the + :c:type:`siginfo_t` structure, namely: :attr:`si_signo`, :attr:`si_code`, + :attr:`si_errno`, :attr:`si_pid`, :attr:`si_uid`, :attr:`si_status`, + :attr:`si_band`. + + Availability: Unix (see the man page :manpage:`sigwaitinfo(2)` for further + information). + + See also :func:`pause`, :func:`sigwait` and :func:`sigtimedwait`. + + .. versionadded:: 3.3 + + +.. function:: sigtimedwait(sigset, (timeout_sec, timeout_nsec)) + + Like :func:`sigtimedwait`, but takes a tuple of ``(seconds, nanoseconds)`` + as an additional argument specifying a timeout. If both *timeout_sec* and + *timeout_nsec* are specified as :const:`0`, a poll is performed. Returns + :const:`None` if a timeout occurs. + + Availability: Unix (see the man page :manpage:`sigtimedwait(2)` for further + information). + + See also :func:`pause`, :func:`sigwait` and :func:`sigwaitinfo`. .. versionadded:: 3.3 diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -169,6 +169,10 @@ * :func:`~signal.pthread_kill`: send a signal to a thread ; * :func:`~signal.sigpending`: examine pending functions ; * :func:`~signal.sigwait`: wait a signal. + * :func:`~signal.sigwaitinfo`: wait for a signal, returning detailed + information about it. + * :func:`~signal.sigtimedwait`: like :func:`~signal.sigwaitinfo` but with a + timeout. * The signal handler writes the signal number as a single byte instead of a nul byte into the wakeup file descriptor. So it is possible to wait more diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -520,6 +520,7 @@ functions. """ def setUp(self): + self.hndl_called = False self.has_pthread_kill = hasattr(signal, 'pthread_kill') def handler(self, signum, frame): @@ -607,45 +608,35 @@ with self.assertRaises(ZeroDivisionError): signal.pthread_kill(current, signum) - @unittest.skipUnless(hasattr(signal, 'sigwait'), - 'need signal.sigwait()') @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') - def test_sigwait(self): - def test(signum): - signal.alarm(1) - received = signal.sigwait([signum]) - if received != signum: - print("sigwait() received %s, not %s" - % (received, signum), - file=sys.stderr) - os._exit(1) - + def wait_helper(self, test, handler, blocked=signal.SIGALRM): signum = signal.SIGALRM - # sigwait must be called with the signal blocked: since the current + # sig*wait* must be called with the signal blocked: since the current # process might have several threads running, we fork() a child process # to have a single thread. pid = os.fork() if pid == 0: # child: block and wait the signal try: - signal.signal(signum, self.handler) - signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + signal.signal(signum, handler) + signal.pthread_sigmask(signal.SIG_BLOCK, [blocked]) # Do the tests test(signum) # The handler must not be called on unblock try: - signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) + signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked]) except ZeroDivisionError: print("the signal handler has been called", file=sys.stderr) os._exit(1) except BaseException as err: print("error: {}".format(err), file=sys.stderr) + sys.stderr.flush() os._exit(1) else: os._exit(0) @@ -655,6 +646,82 @@ @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') + def test_sigwait(self): + def test(signum): + signal.alarm(1) + self.assertEqual(signum, signal.sigwait([signum])) + + self.wait_helper(test, self.handler) + + @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), + 'need signal.sigwaitinfo()') + def test_sigwaitinfo(self): + def test(signum): + signal.alarm(1) + info = signal.sigwaitinfo([signum]) + self.assertEqual(signum, info.si_signo) + + self.wait_helper(test, self.handler) + + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigtimedwait()') + def test_sigtimedwait(self): + def test(signum): + signal.alarm(1) + info = signal.sigtimedwait([signum], (10, 1000)) + self.assertEqual(signum, info.si_signo) + + self.wait_helper(test, self.handler) + + # check that polling with sigtimedwait works + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigtimedwait()') + def test_sigtimedwait_poll(self): + def test(signum): + self.kill(signum) + info = signal.sigtimedwait([signum], (0, 0)) + self.assertEqual(signum, info.si_signo) + + self.wait_helper(test, self.handler) + + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigtimedwait()') + def test_sigtimedwait_timeout(self): + def test(signum): + self.assertEqual(None, signal.sigtimedwait([signum], (1, 35500))) + + self.wait_helper(test, self.handler) + + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigtimedwait()') + def test_sigtimedwait_negative_timeout(self): + signum = signal.SIGALRM + self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, -1)) + self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1)) + self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0)) + + def alarm_handler(self, signum, frame): + self.hndl_called = True + + @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), + 'need signal.sigwaitinfo()') + def test_sigwaitinfo_interrupted(self): + def test(signum): + signal.alarm(1) + try: + signal.sigwaitinfo([signal.SIGUSR1]) + except OSError as e: + if e.errno == errno.EINTR: + self.assertTrue(self.hndl_called) + else: + self.fail("Expected EINTR to be raised by sigwaitinfo") + else: + self.fail("Expected EINTR to be raised by sigwaitinfo") + + self.wait_helper(test, self.alarm_handler, signal.SIGUSR1) + + @unittest.skipUnless(hasattr(signal, 'sigwait'), + 'need signal.sigwait()') @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') @unittest.skipIf(threading is None, "test needs threading module") diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,8 @@ Library ------- +- Issue #12303: Add sigwaitinfo() and sigtimedwait() to the signal module. + - Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -507,7 +507,8 @@ Returns current value of given itimer."); #endif -#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) +#if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ + defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) /* Convert an iterable to a sigset. Return 0 on success, return -1 and raise an exception on error. */ @@ -679,6 +680,140 @@ Wait a signal."); #endif /* #ifdef HAVE_SIGPENDING */ +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) +static int initialized; +static PyStructSequence_Field struct_siginfo_fields[] = { + {"si_signo", "signal number"}, + {"si_code", "signal code"}, + {"si_errno", "errno associated with this signal"}, + {"si_pid", "sending process ID"}, + {"si_uid", "real user ID of sending process"}, + {"si_status", "exit value or signal"}, + {"si_band", "band event for SIGPOLL"}, + {0} +}; + +PyDoc_STRVAR(struct_siginfo__doc__, +"struct_siginfo: Result from sigwaitinfo or sigtimedwait.\n\n\ +This object may be accessed either as a tuple of\n\ +(si_signo, si_code, si_errno, si_pid, si_uid, si_status, si_band),\n\ +or via the attributes si_signo, si_code, and so on."); + +static PyStructSequence_Desc struct_siginfo_desc = { + "signal.struct_siginfo", /* name */ + struct_siginfo__doc__, /* doc */ + struct_siginfo_fields, /* fields */ + 7 /* n_in_sequence */ +}; + +static PyTypeObject SiginfoType; + +static PyObject * +fill_siginfo(siginfo_t *si) +{ + PyObject *result = PyStructSequence_New(&SiginfoType); + if (!result) + return NULL; + + PyStructSequence_SET_ITEM(result, 0, PyLong_FromLong((long)(si->si_signo))); + PyStructSequence_SET_ITEM(result, 1, PyLong_FromLong((long)(si->si_code))); + PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si->si_errno))); + PyStructSequence_SET_ITEM(result, 3, PyLong_FromPid(si->si_pid)); + PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si->si_uid))); + PyStructSequence_SET_ITEM(result, 5, + PyLong_FromLong((long)(si->si_status))); + PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(si->si_band)); + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return result; +} +#endif + +#ifdef HAVE_SIGWAITINFO +static PyObject * +signal_sigwaitinfo(PyObject *self, PyObject *args) +{ + PyObject *signals; + sigset_t set; + siginfo_t si; + int err; + + if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals)) + return NULL; + + if (iterable_to_sigset(signals, &set)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + err = sigwaitinfo(&set, &si); + Py_END_ALLOW_THREADS + if (err == -1) + return PyErr_SetFromErrno(PyExc_OSError); + + return fill_siginfo(&si); +} + +PyDoc_STRVAR(signal_sigwaitinfo_doc, +"sigwaitinfo(sigset) -> struct_siginfo\n\ +\n\ +Wait synchronously for a signal until one of the signals in *sigset* is\n\ +delivered.\n\ +Returns a struct_siginfo containing information about the signal."); +#endif /* #ifdef HAVE_SIGWAITINFO */ + +#ifdef HAVE_SIGTIMEDWAIT +static PyObject * +signal_sigtimedwait(PyObject *self, PyObject *args) +{ + PyObject *signals, *timeout; + struct timespec buf; + sigset_t set; + siginfo_t si; + int err; + + if (!PyArg_ParseTuple(args, "OO:sigtimedwait", &signals, &timeout)) + return NULL; + + if (!PyTuple_Check(timeout) || PyTuple_Size(timeout) != 2) { + PyErr_SetString(PyExc_TypeError, + "sigtimedwait() arg 2 must be a tuple " + "(timeout_sec, timeout_nsec)"); + return NULL; + } else if (!PyArg_ParseTuple(timeout, "ll:sigtimedwait", + &(buf.tv_sec), &(buf.tv_nsec))) + return NULL; + + if (buf.tv_sec < 0 || buf.tv_nsec < 0) { + PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); + return NULL; + } + + if (iterable_to_sigset(signals, &set)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + err = sigtimedwait(&set, &si, &buf); + Py_END_ALLOW_THREADS + if (err == -1) { + if (errno == EAGAIN) + Py_RETURN_NONE; + else + return PyErr_SetFromErrno(PyExc_OSError); + } + + return fill_siginfo(&si); +} + +PyDoc_STRVAR(signal_sigtimedwait_doc, +"sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\ +\n\ +Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\ +nanoseconds)."); +#endif /* #ifdef HAVE_SIGTIMEDWAIT */ + #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) static PyObject * @@ -752,6 +887,14 @@ {"sigwait", (PyCFunction)signal_sigwait, METH_VARARGS, signal_sigwait_doc}, #endif +#ifdef HAVE_SIGWAITINFO + {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, + METH_VARARGS, signal_sigwaitinfo_doc}, +#endif +#ifdef HAVE_SIGTIMEDWAIT + {"sigtimedwait", (PyCFunction)signal_sigtimedwait, + METH_VARARGS, signal_sigtimedwait_doc}, +#endif {NULL, NULL} /* sentinel */ }; @@ -820,6 +963,15 @@ if (m == NULL) return NULL; +#if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) + if (!initialized) + PyStructSequence_InitType(&SiginfoType, &struct_siginfo_desc); + + Py_INCREF((PyObject*) &SiginfoType); + PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); + initialized = 1; +#endif + /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); diff --git a/configure b/configure --- a/configure +++ b/configure @@ -9367,8 +9367,8 @@ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ setgid sethostname \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ - sigaction sigaltstack siginterrupt sigpending \ - sigrelse sigwait snprintf strftime strlcpy symlinkat sync \ + sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm writev _getpty diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2552,8 +2552,8 @@ select sem_open sem_timedwait sem_getvalue sem_unlink sendfile setegid seteuid \ setgid sethostname \ setlocale setregid setreuid setresuid setresgid setsid setpgid setpgrp setpriority setuid setvbuf \ - sigaction sigaltstack siginterrupt sigpending \ - sigrelse sigwait snprintf strftime strlcpy symlinkat sync \ + sigaction sigaltstack siginterrupt sigpending sigrelse \ + sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \ wcscoll wcsftime wcsxfrm writev _getpty) diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -743,9 +743,15 @@ /* Define to 1 if you have the `sigrelse' function. */ #undef HAVE_SIGRELSE +/* Define to 1 if you have the `sigtimedwait' function. */ +#undef HAVE_SIGTIMEDWAIT + /* Define to 1 if you have the `sigwait' function. */ #undef HAVE_SIGWAIT +/* Define to 1 if you have the `sigwaitinfo' function. */ +#undef HAVE_SIGWAITINFO + /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:16:34 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 12:16:34 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Issue_10326=3A_?= =?utf8?q?Fix_regression_to_get_test_cases_to_pickle_again=2E?= Message-ID: http://hg.python.org/cpython/rev/9c337a4c650d changeset: 70965:9c337a4c650d branch: 2.7 parent: 70960:183621c377ef user: Raymond Hettinger date: Sat Jun 25 12:16:25 2011 +0200 summary: Issue 10326: Fix regression to get test cases to pickle again. files: Lib/unittest/case.py | 35 +++++++++++++++++---- Lib/unittest/test/test_case.py | 15 +++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -129,6 +129,27 @@ return True +class _TypeEqualityDict(object): + + def __init__(self, testcase): + self.testcase = testcase + self._store = {} + + def __setitem__(self, key, value): + self._store[key] = value + + def __getitem__(self, key): + value = self._store[key] + if isinstance(value, basestring): + return getattr(self.testcase, value) + return value + + def get(self, key, default=None): + if key in self._store: + return self[key] + return default + + class TestCase(object): """A class whose instances are single test cases. @@ -195,13 +216,13 @@ # Map types to custom assertEqual functions that will compare # instances of said type in more detail to generate a more useful # error message. - self._type_equality_funcs = {} - self.addTypeEqualityFunc(dict, self.assertDictEqual) - self.addTypeEqualityFunc(list, self.assertListEqual) - self.addTypeEqualityFunc(tuple, self.assertTupleEqual) - self.addTypeEqualityFunc(set, self.assertSetEqual) - self.addTypeEqualityFunc(frozenset, self.assertSetEqual) - self.addTypeEqualityFunc(unicode, self.assertMultiLineEqual) + self._type_equality_funcs = _TypeEqualityDict(self) + self.addTypeEqualityFunc(dict, 'assertDictEqual') + self.addTypeEqualityFunc(list, 'assertListEqual') + self.addTypeEqualityFunc(tuple, 'assertTupleEqual') + self.addTypeEqualityFunc(set, 'assertSetEqual') + self.addTypeEqualityFunc(frozenset, 'assertSetEqual') + self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual') def addTypeEqualityFunc(self, typeobj, function): """Add a type specific assertEqual style function to compare a type. diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -1,5 +1,6 @@ import difflib import pprint +import pickle import re import sys @@ -1104,6 +1105,20 @@ self.assertEqual(len(result.errors), 1) self.assertEqual(result.testsRun, 1) + def testPickle(self): + # Issue 10326 + + # Can't use TestCase classes defined in Test class as + # pickle does not work with inner classes + test = unittest.TestCase('run') + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + + # blew up prior to fix + pickled_test = pickle.dumps(test, protocol=protocol) + + unpickled_test = pickle.loads(pickled_test) + self.assertEqual(test, unpickled_test) + if __name__ == '__main__': unittest.main() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 12:33:38 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 12:33:38 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Add_early_draft_of_PEP_to_crea?= =?utf8?q?te_a_new_async_module_and_protocol=2E?= Message-ID: http://hg.python.org/peps/rev/a765fea3c064 changeset: 3888:a765fea3c064 user: Raymond Hettinger date: Sat Jun 25 12:33:30 2011 +0200 summary: Add early draft of PEP to create a new async module and protocol. files: pep-3153.txt | 294 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 294 insertions(+), 0 deletions(-) diff --git a/pep-3153.txt b/pep-3153.txt new file mode 100644 --- /dev/null +++ b/pep-3153.txt @@ -0,0 +1,294 @@ +PEP: XXX +Title: Asynchronous IO support +Version: $Revision$ +Last-Modified: $Date$ +Author: Laurens Van Houtven <_ at lvh.cc> +Status: Draft +Type: Standards Track +Content-Type: text/x-rst +Created: 29-May-2011 +Post-History: TBD + +Abstract +======== + +This PEP describes an abstraction of asynchronous IO for the Python +standard library. + +The goal is to reach a abstraction that can be implemented by many +different asynchronous IO backends and provides a target for library +developers to write code portable between those different backends. + +Rationale +========= + +People who want to write asynchronous code in Python right now have a +few options: + + - ``asyncore`` and ``asynchat`` + - something bespoke, most likely based on the ``select`` module + - using a third party library, such as Twisted_ or gevent_ + +Unfortunately, each of these options has its downsides, which this PEP +tries to address. + +Despite having been part of the Python standard library for a long time, +the asyncore module suffers from fundamental flaws following from +an inflexible API that does not stand up to the expectations of +a modern asynchronous networking module. + +Moreover, its approach is too simplistic to provide developers with all +the tools they need in order to fully exploit the potential of asynchronous +networking. + +The most popular solution right now used in production involves the +use of third party libraries. These often provide satisfactory +solutions, but there is a lack of compatibility between these +libraries, which tends to make codebases very tightly coupled to the +library they use. + +This current lack of portability between different asynchronous IO +libraries causes a lot of duplicated effort for third party library +developers. A sufficiently powerful abstraction could mean that +asynchronous code gets written once, but used everywhere. + +An eventual added goal would be for standard library implementations +of wire and network protocols to evolve towards being real protocol +implementations, as opposed to standalone libraries that do everything +including calling ``recv()`` blockingly. This means they could be +easily reused for both synchronous and asynchronous code. + +.. _Twisted: http://www.twistedmatrix.com/ +.. _gevent: http://www.gevent.org/ + +Communication abstractions +========================== + +Transports +---------- + +Transports provide a uniform API for reading bytes from and writing +bytes to different kinds of connections. Transports in this PEP are +always ordered, reliable, bidirectional, stream-oriented two-endpoint +connections. This might be a TCP socket, an SSL connection, a pipe +(named or otherwise), a serial port... It may abstract a file descriptor +on POSIX platforms or a Handle on Windows or some other data structure +appropriate to a particular platform. It encapsulates all of the +particular implementation details of using that platform data structure +and presents a uniform interface for application developers. + +Transports talk to two things: the other side of the connection on +one hand, and a protocol on the other. It's a bridge between the +specific underlying transfer mechanism and the protocol. Its job can +be described as allowing the protocol to just send and receive bytes, +taking care of all of the magic that needs to happen to those bytes +to be eventually sent across the wire. + +The primary feature of a transport is sending bytes to a protocol and +receiving bytes from the underlying protocol. Writing to the transport +is done using the ``write`` and ``write_sequence`` methods. The latter +method is a performance optimization, to allow software to take +advantage of specific capabilities in some transport +mechanisms. Specifically, this allows transports to use writev_ +instead of write_ or send_, also known as scatter/gather IO. + +A transport can be paused and resumed. This will cause it to buffer +data coming from protocols and stop sending received data to the +protocol. + +A transport can also be closed, half-closed and aborted. A closed +transport will finish writing all of the data queued in it to the +underlying mechanism, and will then stop reading or writing +data. Aborting a transport stops it, closing the connection without +sending any data that is still queued. + +Further writes will result in exceptions being thrown. A half-closed +transport may not be written to anymore, but will still accept +incoming data. + +Protocols +--------- + +Protocols are probably more familiar to new users. The terminology is +consistent with what you would expect from something called a +protocol: the protocols most people think of first, like HTTP, IRC, +SMTP... are all examples of something that would be implemented in a +protocol. + +The shortest useful definition of a protocol is a (usually two-way) +bridge between the transport and the rest of the application logic. A +protocol will receive bytes from a transport and translates that +information into some behavior, typically resulting in some method +calls on an object. Similarly, application logic calls some methods on +the protocol, which the protocol translates into bytes and +communicates to the transport. + +One of the simplest protocols is a line-based protocol, where data is +delimited by ``\r\n``. The protocol will receive bytes from the +transport and buffer them until there is at least one complete +line. Once that's done, it will pass this line along to some +object. Ideally that would be accomplished using a callable or even a +completely separate object composed by the protocol, but it could also +be implemented by subclassing (as is the case with Twisted's +``LineReceiver``). For the other direction, the protocol could have a +``write_line`` method, which adds the required ``\r\n`` and passes the +new bytes buffer on to the transport. + +This PEP suggests a generalized ``LineReceiver`` called +``ChunkProtocol``, where a "chunk" is a message in a stream, delimited +by the specified delimiter. Instances take a delimiter and a callable +that will be called with a chunk of data once it's received (as +opposed to Twisted's subclassing behavior). ``ChunkProtocol`` also has +a ``write_chunk`` method analogous to the ``write_line`` method +described above. + +Why separate protocols and transports? +-------------------------------------- + +This separation between protocol and transport often confuses people +who first come across it. In fact, the standard library itself does +not make this distinction in many cases, particularly not in the API +it provides to users. + +It is nonetheless a very useful distinction. In the worst case, it +simplifies the implementation by clear separation of +concerns. However, it often serves the far more useful purpose of +being able to reuse protocols across different transports. + +Consider a simple RPC protocol. The same bytes may be transferred +across many different transports, for example pipes or sockets. To +help with this, we separate the protocol out from the transport. The +protocol just reads and writes bytes, and doesn't really care what +mechanism is used to eventually transfer those bytes. + +This also allows for protocols to be stacked or nested easily, +allowing for even more code reuse. A common example of this is +JSON-RPC: according to the specification, it can be used across both +sockets and HTTP[#jsonrpc]_ . In practice, it tends to be primarily +encapsulated in HTTP. The protocol-transport abstraction allows us to +build a stack of protocols and transports that allow you to use HTTP +as if it were a transport. For JSON-RPC, that might get you a stack +somewhat like this: + +1. TCP socket transport +2. HTTP protocol +3. HTTP-based transport +4. JSON-RPC protocol +5. Application code + +Flow control +============ + +Consumers +--------- + +Consumers consume bytes produced by producers. Together with +producers, they make flow control possible. + +Consumers primarily play a passive role in flow control. They get +called whenever a producer has some data available. They then process +that data, and typically yield control back to the producer. + +Consumers typically implement buffers of some sort. They make flow +control possible by telling their producer about the current status of +those buffers. A consumer can instruct a producer to stop producing +entirely, stop producing temporarily, or resume producing if it has +been told to pause previously. + +Producers are registered to the consumer using the ``register`` +method. + +Producers +--------- + +Where consumers consume bytes, producers produce them. + +Producers are modeled after the IPushProducer_ interface found in +Twisted. Although there is an IPullProducer_ as well, it is on the +whole far less interesting and therefore probably out of the scope of +this PEP. + +Although producers can be told to stop producing entirely, the two +most interesting methods they have are ``pause`` and ``resume``. These +are usually called by the consumer, to signify whether it is ready to +process ("consume") more data or not. Consumers and producers +cooperate to make flow control possible. + +In addition to the Twisted IPushProducer_ interface, producers have a +``half_register`` method which is called with the consumer when the +consumer tries to register that producer. In most cases, this will +just be a case of setting ``self.consumer = consumer``, but some +producers may require more complex preconditions or behavior when a +consumer is registered. End-users are not supposed to call this method +directly. + +=========================== +Considered API alternatives +=========================== + +Generators as producers +~~~~~~~~~~~~~~~~~~~~~~~ + +Generators have been suggested as way to implement producers. However, +there appear to be a few problems with this. + +First of all, there is a conceptual problem. A generator, in a sense, +is "passive". It needs to be told, through a method call, to take +action. A producer is "active": it initiates those method calls. A +real producer has a symmetric relationship with it's consumer. In the +case of a generator-turned-producer, only the consumer would have a +reference, and the producer is blissfully unaware of the consumer's +existence. + +This conceptual problem translates into a few technical issues as +well. After a successful ``write`` method call on its consumer, a +(push) producer is free to take action once more. In the case of a +generator, it would need to be told, either by asking for the next +object through the iteration protocol (a process which could block +indefinitely), or perhaps by throwing some kind of signal exception +into it. + +This signaling setup may provide a technically feasible solution, but +it is still unsatisfactory. For one, this introduces unwarranted +complexity in the consumer, which now not only needs to understand how +to receive and process data, but also how to ask for new data and deal +with the case of no new data being available. + +This latter edge case is particularly problematic. It needs to be +taken care of, since the entire operation is not allowed to +block. However, generators can not raise an exception on iteration +without terminating, thereby losing the state of the generator. As a +result, signaling a lack of available data would have to be done using +a sentinel value, instead of being done using th exception mechanism. + +Last but not least, nobody produced actually working code +demonstrating how they could be used. + +References +========== + +.. [#jsonrpc] Sections `2.1 `_ and + `2.2 `_ . + +.. _writev: http://pubs.opengroup.org/onlinepubs/009695399/functions/writev.html +.. _write: http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html +.. _send: http://pubs.opengroup.org/onlinepubs/009695399/functions/send.html +.. _IPushProducer: http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IPushProducer.html +.. _IPullProducer: http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.IPullProducer.html + + +Copyright +========= + +This document has been placed in the public domain. + + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Sat Jun 25 13:30:11 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 13:30:11 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDA4?= =?utf8?q?=3A_Fix_relative_import_in_test=5Ffuture5=2Epy=2E__Thanks_Cesare?= =?utf8?q?_Di_Mauro=2E?= Message-ID: http://hg.python.org/cpython/rev/c5fca67a7e8c changeset: 70966:c5fca67a7e8c branch: 3.2 parent: 70962:4a3e528b6b11 user: Mark Dickinson date: Sat Jun 25 13:29:14 2011 +0200 summary: Issue #12408: Fix relative import in test_future5.py. Thanks Cesare Di Mauro. files: Lib/test/test_future5.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_future5.py b/Lib/test/test_future5.py --- a/Lib/test/test_future5.py +++ b/Lib/test/test_future5.py @@ -3,7 +3,7 @@ import sys import unittest -from . import support +from test import support class TestMultipleFeatures(unittest.TestCase): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 13:30:12 2011 From: python-checkins at python.org (mark.dickinson) Date: Sat, 25 Jun 2011 13:30:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=2312408=3A_Merge=2E?= Message-ID: http://hg.python.org/cpython/rev/898c0c8ba8ca changeset: 70967:898c0c8ba8ca parent: 70964:1137f7021b95 parent: 70966:c5fca67a7e8c user: Mark Dickinson date: Sat Jun 25 13:29:49 2011 +0200 summary: Issue #12408: Merge. files: Lib/test/test_future5.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_future5.py b/Lib/test/test_future5.py --- a/Lib/test/test_future5.py +++ b/Lib/test/test_future5.py @@ -3,7 +3,7 @@ import sys import unittest -from . import support +from test import support class TestMultipleFeatures(unittest.TestCase): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 14:57:12 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 14:57:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Issue_11889=3A_?= =?utf8?q?Clarify_docs_for_enumerate=2E?= Message-ID: http://hg.python.org/cpython/rev/0ca8ffffd90b changeset: 70968:0ca8ffffd90b branch: 2.7 parent: 70965:9c337a4c650d user: Raymond Hettinger date: Sat Jun 25 14:57:06 2011 +0200 summary: Issue 11889: Clarify docs for enumerate. files: Doc/library/functions.rst | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -341,14 +341,13 @@ :term:`iterator`, or some other object which supports iteration. The :meth:`!next` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the - corresponding value obtained from iterating over *sequence*:: + values obtained from iterating over *sequence*:: - >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): - print i, season - 1 Spring - 2 Summer - 3 Fall - 4 Winter + >>> seasons = ['Spring', 'Summer', 'Fall', 'Winter'] + >>> list(enumerate(seasons)) + [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] + >>> list(enumerate(seasons, start=1)) + [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')] Equivalent to:: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 15:01:21 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 15:01:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Issue_11889=3A_?= =?utf8?q?Clarify_docs_for_enumerate=2E?= Message-ID: http://hg.python.org/cpython/rev/d0df12b32522 changeset: 70969:d0df12b32522 branch: 3.2 parent: 70966:c5fca67a7e8c user: Raymond Hettinger date: Sat Jun 25 15:00:14 2011 +0200 summary: Issue 11889: Clarify docs for enumerate. files: Doc/library/functions.rst | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -331,14 +331,13 @@ :term:`iterator`, or some other object which supports iteration. The :meth:`__next__` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the - corresponding value obtained from iterating over *iterable*. + values obtained from iterating over *iterable*. - >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): - print(i, season) - 1 Spring - 2 Summer - 3 Fall - 4 Winter + >>> seasons = ['Spring', 'Summer', 'Fall', 'Winter'] + >>> list(enumerate(seasons)) + [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] + >>> list(enumerate(seasons, start=1)) + [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')] Equivalent to:: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 15:01:22 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 15:01:22 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_11889=3A_Clarify_docs_for_enumerate=2E?= Message-ID: http://hg.python.org/cpython/rev/9b827e3998f6 changeset: 70970:9b827e3998f6 parent: 70967:898c0c8ba8ca parent: 70969:d0df12b32522 user: Raymond Hettinger date: Sat Jun 25 15:00:46 2011 +0200 summary: Issue 11889: Clarify docs for enumerate. files: Doc/library/functions.rst | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -331,14 +331,13 @@ :term:`iterator`, or some other object which supports iteration. The :meth:`__next__` method of the iterator returned by :func:`enumerate` returns a tuple containing a count (from *start* which defaults to 0) and the - corresponding value obtained from iterating over *iterable*. + values obtained from iterating over *iterable*. - >>> for i, season in enumerate('Spring Summer Fall Winter'.split(), start=1): - print(i, season) - 1 Spring - 2 Summer - 3 Fall - 4 Winter + >>> seasons = ['Spring', 'Summer', 'Fall', 'Winter'] + >>> list(enumerate(seasons)) + [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] + >>> list(enumerate(seasons, start=1)) + [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')] Equivalent to:: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 15:04:39 2011 From: python-checkins at python.org (ross.lagerwall) Date: Sat, 25 Jun 2011 15:04:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Fix_test=5Fsignal_on_Window?= =?utf8?q?s_after_=2312303=2E?= Message-ID: http://hg.python.org/cpython/rev/768234f5c246 changeset: 70971:768234f5c246 user: Ross Lagerwall date: Sat Jun 25 15:03:52 2011 +0200 summary: Fix test_signal on Windows after #12303. files: Lib/test/test_signal.py | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -611,7 +611,7 @@ @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') - def wait_helper(self, test, handler, blocked=signal.SIGALRM): + def wait_helper(self, test, handler, blocked): signum = signal.SIGALRM # sig*wait* must be called with the signal blocked: since the current @@ -651,7 +651,7 @@ signal.alarm(1) self.assertEqual(signum, signal.sigwait([signum])) - self.wait_helper(test, self.handler) + self.wait_helper(test, self.handler, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), 'need signal.sigwaitinfo()') @@ -661,7 +661,7 @@ info = signal.sigwaitinfo([signum]) self.assertEqual(signum, info.si_signo) - self.wait_helper(test, self.handler) + self.wait_helper(test, self.handler, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') @@ -671,7 +671,7 @@ info = signal.sigtimedwait([signum], (10, 1000)) self.assertEqual(signum, info.si_signo) - self.wait_helper(test, self.handler) + self.wait_helper(test, self.handler, signal.SIGALRM) # check that polling with sigtimedwait works @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), @@ -682,7 +682,7 @@ info = signal.sigtimedwait([signum], (0, 0)) self.assertEqual(signum, info.si_signo) - self.wait_helper(test, self.handler) + self.wait_helper(test, self.handler, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') @@ -690,7 +690,7 @@ def test(signum): self.assertEqual(None, signal.sigtimedwait([signum], (1, 35500))) - self.wait_helper(test, self.handler) + self.wait_helper(test, self.handler, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 15:54:58 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 15:54:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_11758=3A_increase_xml?= =?utf8?q?=2Edom=2Eminidom_test_coverage_=28contributed_by_mdorn=2C?= Message-ID: http://hg.python.org/cpython/rev/79d61e2050cd changeset: 70972:79d61e2050cd user: Raymond Hettinger date: Sat Jun 25 15:54:52 2011 +0200 summary: Issue 11758: increase xml.dom.minidom test coverage (contributed by mdorn, reviewed by Sandro Tosi). files: Lib/test/test_minidom.py | 42 ++++++++++++++++++++++++++- 1 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -279,6 +279,7 @@ child.setAttribute("def", "ghi") self.confirm(len(child.attributes) == 1) + self.assertRaises(xml.dom.NotFoundErr, child.removeAttribute, "foo") child.removeAttribute("def") self.confirm(len(child.attributes) == 0) dom.unlink() @@ -290,6 +291,8 @@ child.setAttributeNS("http://www.w3.org", "xmlns:python", "http://www.python.org") child.setAttributeNS("http://www.python.org", "python:abcattr", "foo") + self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNS, + "foo", "http://www.python.org") self.confirm(len(child.attributes) == 2) child.removeAttributeNS("http://www.python.org", "abcattr") self.confirm(len(child.attributes) == 1) @@ -301,11 +304,23 @@ child.setAttribute("spam", "jam") self.confirm(len(child.attributes) == 1) node = child.getAttributeNode("spam") + self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNode, + None) child.removeAttributeNode(node) self.confirm(len(child.attributes) == 0 and child.getAttributeNode("spam") is None) + dom2 = Document() + child2 = dom2.appendChild(dom.createElement("foo")) + self.assertRaises(xml.dom.NotFoundErr, child.removeAttributeNode, + node) dom.unlink() + def testHasAttribute(self): + dom = Document() + child = dom.appendChild(dom.createElement("foo")) + child.setAttribute("spam", "jam") + self.confirm(child.hasAttribute("spam")) + def testChangeAttr(self): dom = parseString("") el = dom.documentElement @@ -353,7 +368,16 @@ def testGetAttribute(self): pass - def testGetAttributeNS(self): pass + def testGetAttributeNS(self): + dom = Document() + child = dom.appendChild( + dom.createElementNS("http://www.python.org", "python:abc")) + child.setAttributeNS("http://www.w3.org", "xmlns:python", + "http://www.python.org") + self.assertEqual(child.getAttributeNS("http://www.w3.org", "python"), + 'http://www.python.org') + self.assertEqual(child.getAttributeNS("http://www.w3.org", "other"), + '') def testGetAttributeNode(self): pass @@ -537,7 +561,13 @@ def testFirstChild(self): pass - def testHasChildNodes(self): pass + def testHasChildNodes(self): + dom = parseString("") + doc = dom.documentElement + self.assertTrue(dom.hasChildNodes()) + dom2 = parseString("") + doc2 = dom2.documentElement + self.assertFalse(doc2.hasChildNodes()) def _testCloneElementCopiesAttributes(self, e1, e2, test): attrs1 = e1.attributes @@ -1439,6 +1469,14 @@ doc2 = parseString(doc.toxml()) self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) + def testDocRemoveChild(self): + doc = parse(tstfile) + title_tag = doc.documentElement.getElementsByTagName("TITLE")[0] + self.assertRaises( xml.dom.NotFoundErr, doc.removeChild, title_tag) + num_children_before = len(doc.childNodes) + doc.removeChild(doc.childNodes[0]) + num_children_after = len(doc.childNodes) + self.assertTrue(num_children_after == num_children_before - 1) def test_main(): run_unittest(MinidomTest) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 16:28:22 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 16:28:22 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Issue_12086=3A_?= =?utf8?q?add_example_showing_how_to_use_name_mangling=2E?= Message-ID: http://hg.python.org/cpython/rev/68bc3c5960a4 changeset: 70973:68bc3c5960a4 branch: 2.7 parent: 70968:0ca8ffffd90b user: Raymond Hettinger date: Sat Jun 25 16:28:07 2011 +0200 summary: Issue 12086: add example showing how to use name mangling. files: Doc/tutorial/classes.rst | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -553,6 +553,28 @@ without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class. +Name mangling is helpful for letting subclasses override methods without +breaking intraclass method calls. For example:: + + class Mapping: + def __init__(self, iterable): + self.items_list = [] + self.__update(iterable) + + def update(self, iterable): + for item in iterable: + self.items_list.append(item) + + __update = update # private copy of original update() method + + class MappingSubclass(Mapping): + + def update(self, keys, values): + # provides new signature for update() + # but does not break __init__() + for item in zip(keys, values): + self.items_list.append(item) + Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 16:31:22 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 16:31:22 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Issue_12086=3A_?= =?utf8?q?add_example_showing_how_to_use_name_mangling=2E?= Message-ID: http://hg.python.org/cpython/rev/79f9698777b7 changeset: 70974:79f9698777b7 branch: 3.2 parent: 70969:d0df12b32522 user: Raymond Hettinger date: Sat Jun 25 16:30:39 2011 +0200 summary: Issue 12086: add example showing how to use name mangling. files: Doc/tutorial/classes.rst | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -595,6 +595,28 @@ without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class. +Name mangling is helpful for letting subclasses override methods without +breaking intraclass method calls. For example:: + + class Mapping: + def __init__(self, iterable): + self.items_list = [] + self.__update(iterable) + + def update(self, iterable): + for item in iterable: + self.items_list.append(item) + + __update = update # private copy of original update() method + + class MappingSubclass(Mapping): + + def update(self, keys, values): + # provides new signature for update() + # but does not break __init__() + for item in zip(keys, values): + self.items_list.append(item) + Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 16:31:22 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 16:31:22 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_12086=3A_add_example_showing_how_to_use_name_mangling?= =?utf8?q?=2E?= Message-ID: http://hg.python.org/cpython/rev/fca745bc70be changeset: 70975:fca745bc70be parent: 70972:79d61e2050cd parent: 70974:79f9698777b7 user: Raymond Hettinger date: Sat Jun 25 16:31:06 2011 +0200 summary: Issue 12086: add example showing how to use name mangling. files: Doc/tutorial/classes.rst | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -595,6 +595,28 @@ without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class. +Name mangling is helpful for letting subclasses override methods without +breaking intraclass method calls. For example:: + + class Mapping: + def __init__(self, iterable): + self.items_list = [] + self.__update(iterable) + + def update(self, iterable): + for item in iterable: + self.items_list.append(item) + + __update = update # private copy of original update() method + + class MappingSubclass(Mapping): + + def update(self, keys, values): + # provides new signature for update() + # but does not break __init__() + for item in zip(keys, values): + self.items_list.append(item) + Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 17:14:59 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 17:14:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Issue_11802=3A_?= =?utf8?q?_filecmp_cache_was_growing_without_bound=2E?= Message-ID: http://hg.python.org/cpython/rev/11568c59d9d4 changeset: 70976:11568c59d9d4 branch: 2.7 parent: 70973:68bc3c5960a4 user: Raymond Hettinger date: Sat Jun 25 17:14:53 2011 +0200 summary: Issue 11802: filecmp cache was growing without bound. files: Lib/filecmp.py | 11 ++++++----- Misc/NEWS | 3 +++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Lib/filecmp.py b/Lib/filecmp.py --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -48,11 +48,12 @@ if s1[1] != s2[1]: return False - result = _cache.get((f1, f2)) - if result and (s1, s2) == result[:2]: - return result[2] - outcome = _do_cmp(f1, f2) - _cache[f1, f2] = s1, s2, outcome + outcome = _cache.get((f1, f2, s1, s2)) + if outcome is None: + outcome = _do_cmp(f1, f2) + if len(_cache) > 100: # limit the maximum size of the cache + _cache.clear() + _cache[f1, f2, s1, s2] = outcome return outcome def _sig(st): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,9 @@ Library ------- +- Issue #11802: The cache in filecmp now has a maximum size of 100 so that + it won't grow without bound. + - Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 17:21:28 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 17:21:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Issue_11802=3A_?= =?utf8?q?_filecmp_cache_was_growing_without_bound=2E?= Message-ID: http://hg.python.org/cpython/rev/2bacaf6a80c4 changeset: 70977:2bacaf6a80c4 branch: 3.2 parent: 70974:79f9698777b7 user: Raymond Hettinger date: Sat Jun 25 17:20:21 2011 +0200 summary: Issue 11802: filecmp cache was growing without bound. files: Lib/filecmp.py | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/filecmp.py b/Lib/filecmp.py --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -48,11 +48,12 @@ if s1[1] != s2[1]: return False - result = _cache.get((f1, f2)) - if result and (s1, s2) == result[:2]: - return result[2] - outcome = _do_cmp(f1, f2) - _cache[f1, f2] = s1, s2, outcome + outcome = _cache.get((f1, f2, s1, s2)) + if outcome is None: + outcome = _do_cmp(f1, f2) + if len(_cache) > 100: # limit the maximum size of the cache + _cache.clear() + _cache[f1, f2, s1, s2] = outcome return outcome def _sig(st): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 17:21:29 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sat, 25 Jun 2011 17:21:29 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_11802=3A__filecmp_cache_was_growing_without_bound=2E?= Message-ID: http://hg.python.org/cpython/rev/8f4466619e1c changeset: 70978:8f4466619e1c parent: 70975:fca745bc70be parent: 70977:2bacaf6a80c4 user: Raymond Hettinger date: Sat Jun 25 17:21:04 2011 +0200 summary: Issue 11802: filecmp cache was growing without bound. files: Lib/filecmp.py | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/filecmp.py b/Lib/filecmp.py --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -48,11 +48,12 @@ if s1[1] != s2[1]: return False - result = _cache.get((f1, f2)) - if result and (s1, s2) == result[:2]: - return result[2] - outcome = _do_cmp(f1, f2) - _cache[f1, f2] = s1, s2, outcome + outcome = _cache.get((f1, f2, s1, s2)) + if outcome is None: + outcome = _do_cmp(f1, f2) + if len(_cache) > 100: # limit the maximum size of the cache + _cache.clear() + _cache[f1, f2, s1, s2] = outcome return outcome def _sig(st): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 17:38:59 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 17:38:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_=2312341=3A_add_coverage_fi?= =?utf8?q?les/dirs_to_=2Ehgignore=2E_Patch_by_Sandro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/ef306bd1d122 changeset: 70979:ef306bd1d122 user: Ezio Melotti date: Sat Jun 25 12:36:38 2011 +0300 summary: #12341: add coverage files/dirs to .hgignore. Patch by Sandro Tosi. files: .bzrignore | 3 +++ .gitignore | 3 +++ .hgignore | 3 +++ 3 files changed, 9 insertions(+), 0 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -40,3 +40,6 @@ .coverage coverage/* htmlcov/* +.coverage +coverage/* +htmlcov/* diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,6 @@ .coverage coverage/ htmlcov/ +.coverage +coverage/ +htmlcov/ diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -73,3 +73,6 @@ .coverage coverage/ htmlcov/ +.coverage +coverage/ +htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:31:10 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:31:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Backed_out_changeset_ef306b?= =?utf8?q?d1d122?= Message-ID: http://hg.python.org/cpython/rev/d7acf357ad79 changeset: 70980:d7acf357ad79 user: Ezio Melotti date: Sat Jun 25 20:10:39 2011 +0300 summary: Backed out changeset ef306bd1d122 files: .bzrignore | 3 --- .gitignore | 3 --- .hgignore | 3 --- 3 files changed, 0 insertions(+), 9 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -40,6 +40,3 @@ .coverage coverage/* htmlcov/* -.coverage -coverage/* -htmlcov/* diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,3 @@ .coverage coverage/ htmlcov/ -.coverage -coverage/ -htmlcov/ diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -73,6 +73,3 @@ .coverage coverage/ htmlcov/ -.coverage -coverage/ -htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:31:11 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:31:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Use_correct_markup_in_zipim?= =?utf8?q?port=2Erst=2E_Patch_by_Sara_Magliacane=2E?= Message-ID: http://hg.python.org/cpython/rev/4dcb49395c7a changeset: 70981:4dcb49395c7a parent: 70979:ef306bd1d122 user: Ezio Melotti date: Sat Jun 25 19:40:06 2011 +0300 summary: Use correct markup in zipimport.rst. Patch by Sara Magliacane. files: Doc/library/zipimport.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -9,11 +9,11 @@ This module adds the ability to import Python modules (:file:`\*.py`, :file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not needed to use the :mod:`zipimport` module explicitly; it is automatically used -by the built-in :keyword:`import` mechanism for ``sys.path`` items that are paths +by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. -Typically, ``sys.path`` is a list of directory names as strings. This module -also allows an item of ``sys.path`` to be a string naming a ZIP file archive. +Typically, :data:`sys.path` is a list of directory names as strings. This module +also allows an item of :data:`sys.path` to be a string naming a ZIP file archive. The ZIP archive can contain a subdirectory structure to support package imports, and a path within the archive can be specified to only import from a subdirectory. For example, the path :file:`/tmp/example.zip/lib/` would only -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:31:12 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:31:12 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzEyMzQxOiBhZGQg?= =?utf8?q?coverage_files/dirs_to_=2Ehgignore=2E_Patch_by_Sandro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/ee9eb4e05180 changeset: 70982:ee9eb4e05180 branch: 2.7 parent: 70976:11568c59d9d4 user: Ezio Melotti date: Sat Jun 25 20:19:54 2011 +0300 summary: #12341: add coverage files/dirs to .hgignore. Patch by Sandro Tosi. files: .bzrignore | 3 +++ .hgignore | 3 +++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/.bzrignore b/.bzrignore --- a/.bzrignore +++ b/.bzrignore @@ -33,3 +33,6 @@ Lib/test/data/* Lib/lib2to3/Grammar*.pickle Lib/lib2to3/PatternGrammar*.pickle +.coverage +coverage/* +htmlcov/* diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -62,3 +62,6 @@ PCbuild/*.ncb PCbuild/*.bsc PCbuild/Win32-temp-* +.coverage +coverage/ +htmlcov/ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:31:13 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:31:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Use_correct_mar?= =?utf8?q?kup_in_zipimport=2Erst=2E_Patch_by_Sara_Magliacane=2E?= Message-ID: http://hg.python.org/cpython/rev/4f936d99d9ab changeset: 70983:4f936d99d9ab branch: 3.2 parent: 70977:2bacaf6a80c4 user: Ezio Melotti date: Sat Jun 25 19:40:06 2011 +0300 summary: Use correct markup in zipimport.rst. Patch by Sara Magliacane. files: Doc/library/zipimport.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -9,11 +9,11 @@ This module adds the ability to import Python modules (:file:`\*.py`, :file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not needed to use the :mod:`zipimport` module explicitly; it is automatically used -by the built-in :keyword:`import` mechanism for ``sys.path`` items that are paths +by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. -Typically, ``sys.path`` is a list of directory names as strings. This module -also allows an item of ``sys.path`` to be a string naming a ZIP file archive. +Typically, :data:`sys.path` is a list of directory names as strings. This module +also allows an item of :data:`sys.path` to be a string naming a ZIP file archive. The ZIP archive can contain a subdirectory structure to support package imports, and a path within the archive can be specified to only import from a subdirectory. For example, the path :file:`/tmp/example.zip/lib/` would only -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:31:15 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:31:15 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?b?KTogTWVyZ2UgaGVhZHMu?= Message-ID: http://hg.python.org/cpython/rev/039c316bd157 changeset: 70984:039c316bd157 parent: 70980:d7acf357ad79 parent: 70981:4dcb49395c7a user: Ezio Melotti date: Sat Jun 25 20:30:52 2011 +0300 summary: Merge heads. files: Doc/library/zipimport.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -9,11 +9,11 @@ This module adds the ability to import Python modules (:file:`\*.py`, :file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not needed to use the :mod:`zipimport` module explicitly; it is automatically used -by the built-in :keyword:`import` mechanism for ``sys.path`` items that are paths +by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. -Typically, ``sys.path`` is a list of directory names as strings. This module -also allows an item of ``sys.path`` to be a string naming a ZIP file archive. +Typically, :data:`sys.path` is a list of directory names as strings. This module +also allows an item of :data:`sys.path` to be a string naming a ZIP file archive. The ZIP archive can contain a subdirectory structure to support package imports, and a path within the archive can be specified to only import from a subdirectory. For example, the path :file:`/tmp/example.zip/lib/` would only -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sat Jun 25 19:50:59 2011 From: python-checkins at python.org (ezio.melotti) Date: Sat, 25 Jun 2011 19:50:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Use_correct_mar?= =?utf8?q?kup_in_zipimport=2Erst=2E_Patch_by_Sara_Magliacane=2E?= Message-ID: http://hg.python.org/cpython/rev/5adc872bbca2 changeset: 70985:5adc872bbca2 branch: 2.7 parent: 70982:ee9eb4e05180 user: Ezio Melotti date: Sat Jun 25 19:40:06 2011 +0300 summary: Use correct markup in zipimport.rst. Patch by Sara Magliacane. files: Doc/library/zipimport.rst | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -12,11 +12,11 @@ This module adds the ability to import Python modules (:file:`\*.py`, :file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not needed to use the :mod:`zipimport` module explicitly; it is automatically used -by the built-in :keyword:`import` mechanism for ``sys.path`` items that are paths +by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. -Typically, ``sys.path`` is a list of directory names as strings. This module -also allows an item of ``sys.path`` to be a string naming a ZIP file archive. +Typically, :data:`sys.path` is a list of directory names as strings. This module +also allows an item of :data:`sys.path` to be a string naming a ZIP file archive. The ZIP archive can contain a subdirectory structure to support package imports, and a path within the archive can be specified to only import from a subdirectory. For example, the path :file:`/tmp/example.zip/lib/` would only -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 05:02:28 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 26 Jun 2011 05:02:28 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Record_Guido=27s_acceptance_of?= =?utf8?q?_PEP_380?= Message-ID: http://hg.python.org/peps/rev/9f7a0b4e38a7 changeset: 3889:9f7a0b4e38a7 user: Nick Coghlan date: Sun Jun 26 13:02:17 2011 +1000 summary: Record Guido's acceptance of PEP 380 files: pep-0380.txt | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pep-0380.txt b/pep-0380.txt --- a/pep-0380.txt +++ b/pep-0380.txt @@ -3,11 +3,11 @@ Version: $Revision$ Last-Modified: $Date$ Author: Gregory Ewing -Status: Draft +Status: Accepted Type: Standards Track Content-Type: text/x-rst Created: 13-Feb-2009 -Python-Version: 3.x +Python-Version: 3.3 Post-History: @@ -23,6 +23,12 @@ The new syntax also opens up some opportunities for optimisation when one generator re-yields values produced by another. +PEP Acceptance +============== + +Guido officially `accepted the PEP`_ on 26th June, 2011. + +.. _accepted the PEP: http://mail.python.org/pipermail/python-dev/2011-June/112010.html Motivation ========== -- Repository URL: http://hg.python.org/peps From solipsis at pitrou.net Sun Jun 26 05:08:31 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 26 Jun 2011 05:08:31 +0200 Subject: [Python-checkins] Daily reference leaks (039c316bd157): sum=300 Message-ID: results for 039c316bd157 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogG3W5GZ', '-x'] From python-checkins at python.org Sun Jun 26 05:48:42 2011 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 26 Jun 2011 05:48:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_Issue10020_?= =?utf8?q?-_Doc_update_to_sqlite3_module_in_2=2E7_branch=2E?= Message-ID: http://hg.python.org/cpython/rev/804a60029091 changeset: 70986:804a60029091 branch: 2.7 user: Senthil Kumaran date: Sat Jun 25 20:48:21 2011 -0700 summary: Fix Issue10020 - Doc update to sqlite3 module in 2.7 branch. files: Doc/library/sqlite3.rst | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -378,6 +378,8 @@ .. literalinclude:: ../includes/sqlite3/load_extension.py + Loadable extensions are disabled by default. See [#f1]_ + .. method:: Connection.load_extension(path) .. versionadded:: 2.7 @@ -386,6 +388,8 @@ enable extension loading with :meth:`enable_load_extension` before you can use this routine. + Loadable extensions are disabled by default. See [#f1]_ + .. attribute:: Connection.row_factory You can change this attribute to a callable that accepts the cursor and the @@ -893,3 +897,11 @@ The only exception is calling the :meth:`~Connection.interrupt` method, which only makes sense to call from a different thread. + +.. rubric:: Footnotes + +.. [#f1] The sqlite3 module is not built with loadable extension support by + default, because some platforms (notably Mac OS X) have SQLite libraries which + are compiled without this feature. To get loadable extension support, you must + modify setup.py and remove the line that sets SQLITE_OMIT_LOAD_EXTENSION. + -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 05:54:51 2011 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 26 Jun 2011 05:54:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_map_cells_to_arg_slots_at_c?= =?utf8?q?ode_creation_time_=28closes_=2312399=29?= Message-ID: http://hg.python.org/cpython/rev/c5b0585624ef changeset: 70987:c5b0585624ef parent: 70984:039c316bd157 user: Benjamin Peterson date: Sat Jun 25 22:54:45 2011 -0500 summary: map cells to arg slots at code creation time (closes #12399) This removes nested loops in PyEval_EvalCodeEx. files: Include/code.h | 6 ++ Lib/test/test_sys.py | 2 +- Objects/codeobject.c | 94 ++++++++++++++++++++++--------- Python/ceval.c | 64 +++++---------------- 4 files changed, 88 insertions(+), 78 deletions(-) diff --git a/Include/code.h b/Include/code.h --- a/Include/code.h +++ b/Include/code.h @@ -22,6 +22,7 @@ PyObject *co_freevars; /* tuple of strings (free variable names) */ PyObject *co_cellvars; /* tuple of strings (cell variable names) */ /* The rest doesn't count for hash or comparisons */ + unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ int co_firstlineno; /* first source line number */ @@ -57,6 +58,11 @@ #define CO_FUTURE_BARRY_AS_BDFL 0x40000 +/* This value is found in the co_cell2arg array when the associated cell + variable does not correspond to an argument. The maximum number of + arguments is 255 (indexed up to 254), so 255 work as a special flag.*/ +#define CO_CELL_NOT_AN_ARG 255 + /* This should be defined if a future statement modifies the syntax. For example, when a keyword is added. */ diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -665,7 +665,7 @@ return inner check(get_cell().__closure__[0], size(h + 'P')) # code - check(get_cell().__code__, size(h + '5i8Pi3P')) + check(get_cell().__code__, size(h + '5i9Pi3P')) # complex check(complex(0,1), size(h + '2d')) # method_descriptor (descriptor object) diff --git a/Objects/codeobject.c b/Objects/codeobject.c --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -51,7 +51,8 @@ PyObject *lnotab) { PyCodeObject *co; - Py_ssize_t i; + unsigned char *cell2arg = NULL; + Py_ssize_t i, n_cellvars; /* Check argument types */ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || @@ -68,12 +69,13 @@ PyErr_BadInternalCall(); return NULL; } + n_cellvars = PyTuple_GET_SIZE(cellvars); intern_strings(names); intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); /* Intern selected string constants */ - for (i = PyTuple_Size(consts); --i >= 0; ) { + for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { PyObject *v = PyTuple_GetItem(consts, i); if (!PyUnicode_Check(v)) continue; @@ -81,35 +83,67 @@ continue; PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); } + /* Create mapping between cells and arguments if needed. */ + if (n_cellvars) { + Py_ssize_t total_args = argcount + kwonlyargcount + + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); + Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars; + int used_cell2arg = 0; + cell2arg = PyMem_MALLOC(alloc_size); + if (cell2arg == NULL) + return NULL; + memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size); + /* Find cells which are also arguments. */ + for (i = 0; i < n_cellvars; i++) { + Py_ssize_t j; + PyObject *cell = PyTuple_GET_ITEM(cellvars, i); + for (j = 0; j < total_args; j++) { + PyObject *arg = PyTuple_GET_ITEM(varnames, j); + if (!PyUnicode_Compare(cell, arg)) { + cell2arg[i] = j; + used_cell2arg = 1; + break; + } + } + } + if (!used_cell2arg) { + PyMem_FREE(cell2arg); + cell2arg = NULL; + } + } co = PyObject_NEW(PyCodeObject, &PyCode_Type); - if (co != NULL) { - co->co_argcount = argcount; - co->co_kwonlyargcount = kwonlyargcount; - co->co_nlocals = nlocals; - co->co_stacksize = stacksize; - co->co_flags = flags; - Py_INCREF(code); - co->co_code = code; - Py_INCREF(consts); - co->co_consts = consts; - Py_INCREF(names); - co->co_names = names; - Py_INCREF(varnames); - co->co_varnames = varnames; - Py_INCREF(freevars); - co->co_freevars = freevars; - Py_INCREF(cellvars); - co->co_cellvars = cellvars; - Py_INCREF(filename); - co->co_filename = filename; - Py_INCREF(name); - co->co_name = name; - co->co_firstlineno = firstlineno; - Py_INCREF(lnotab); - co->co_lnotab = lnotab; - co->co_zombieframe = NULL; - co->co_weakreflist = NULL; + if (co == NULL) { + if (cell2arg) + PyMem_FREE(cell2arg); + return NULL; } + co->co_argcount = argcount; + co->co_kwonlyargcount = kwonlyargcount; + co->co_nlocals = nlocals; + co->co_stacksize = stacksize; + co->co_flags = flags; + Py_INCREF(code); + co->co_code = code; + Py_INCREF(consts); + co->co_consts = consts; + Py_INCREF(names); + co->co_names = names; + Py_INCREF(varnames); + co->co_varnames = varnames; + Py_INCREF(freevars); + co->co_freevars = freevars; + Py_INCREF(cellvars); + co->co_cellvars = cellvars; + co->co_cell2arg = cell2arg; + Py_INCREF(filename); + co->co_filename = filename; + Py_INCREF(name); + co->co_name = name; + co->co_firstlineno = firstlineno; + Py_INCREF(lnotab); + co->co_lnotab = lnotab; + co->co_zombieframe = NULL; + co->co_weakreflist = NULL; return co; } @@ -330,6 +364,8 @@ Py_XDECREF(co->co_filename); Py_XDECREF(co->co_name); Py_XDECREF(co->co_lnotab); + if (co->co_cell2arg != NULL) + PyMem_FREE(co->co_cell2arg); if (co->co_zombieframe != NULL) PyObject_GC_Del(co->co_zombieframe); if (co->co_weakreflist != NULL) diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3357,56 +3357,24 @@ } /* Allocate and initialize storage for cell vars, and copy free - vars into frame. This isn't too efficient right now. */ - if (PyTuple_GET_SIZE(co->co_cellvars)) { - int i, j, nargs, found; - Py_UNICODE *cellname, *argname; + vars into frame. */ + for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { PyObject *c; - - nargs = total_args; - if (co->co_flags & CO_VARARGS) - nargs++; - if (co->co_flags & CO_VARKEYWORDS) - nargs++; - - /* Initialize each cell var, taking into account - cell vars that are initialized from arguments. - - Should arrange for the compiler to put cellvars - that are arguments at the beginning of the cellvars - list so that we can march over it more efficiently? - */ - for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) { - cellname = PyUnicode_AS_UNICODE( - PyTuple_GET_ITEM(co->co_cellvars, i)); - found = 0; - for (j = 0; j < nargs; j++) { - argname = PyUnicode_AS_UNICODE( - PyTuple_GET_ITEM(co->co_varnames, j)); - if (Py_UNICODE_strcmp(cellname, argname) == 0) { - c = PyCell_New(GETLOCAL(j)); - if (c == NULL) - goto fail; - GETLOCAL(co->co_nlocals + i) = c; - found = 1; - break; - } - } - if (found == 0) { - c = PyCell_New(NULL); - if (c == NULL) - goto fail; - SETLOCAL(co->co_nlocals + i, c); - } - } + int arg; + /* Possibly account for the cell variable being an argument. */ + if (co->co_cell2arg != NULL && + (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG) + c = PyCell_New(GETLOCAL(arg)); + else + c = PyCell_New(NULL); + if (c == NULL) + goto fail; + SETLOCAL(co->co_nlocals + i, c); } - if (PyTuple_GET_SIZE(co->co_freevars)) { - int i; - for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); - Py_INCREF(o); - freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; - } + for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + Py_INCREF(o); + freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; } if (co->co_flags & CO_GENERATOR) { -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 10:38:38 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 10:38:38 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzExNjY5OiByZXBo?= =?utf8?q?rase_footnote_in_the_Compound_Statements_page=2E?= Message-ID: http://hg.python.org/cpython/rev/b11e7bc76d07 changeset: 70988:b11e7bc76d07 branch: 2.7 parent: 70986:804a60029091 user: Ezio Melotti date: Sun Jun 26 11:25:28 2011 +0300 summary: #11669: rephrase footnote in the Compound Statements page. files: Doc/reference/compound_stmts.rst | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -562,8 +562,9 @@ .. rubric:: Footnotes -.. [#] The exception is propagated to the invocation stack only if there is no - :keyword:`finally` clause that negates the exception. +.. [#] The exception is propagated to the invocation stack unless + there is a :keyword:`finally` clause which happens to raise another + exception. That new exception causes the old one to be lost. .. [#] Currently, control "flows off the end" except in the case of an exception or the execution of a :keyword:`return`, :keyword:`continue`, or :keyword:`break` -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 10:38:38 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 10:38:38 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExNjY5OiByZXBo?= =?utf8?q?rase_footnote_in_the_Compound_Statements_page=2E?= Message-ID: http://hg.python.org/cpython/rev/74e9f94d8440 changeset: 70989:74e9f94d8440 branch: 3.2 parent: 70983:4f936d99d9ab user: Ezio Melotti date: Sun Jun 26 11:25:28 2011 +0300 summary: #11669: rephrase footnote in the Compound Statements page. files: Doc/reference/compound_stmts.rst | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -615,8 +615,9 @@ .. rubric:: Footnotes -.. [#] The exception is propagated to the invocation stack only if there is no - :keyword:`finally` clause that negates the exception. +.. [#] The exception is propagated to the invocation stack unless + there is a :keyword:`finally` clause which happens to raise another + exception. That new exception causes the old one to be lost. .. [#] Currently, control "flows off the end" except in the case of an exception or the execution of a :keyword:`return`, :keyword:`continue`, or -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 10:38:39 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 10:38:39 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=2311669=3A_merge_with_3=2E2=2E?= Message-ID: http://hg.python.org/cpython/rev/a7099a3b5e5f changeset: 70990:a7099a3b5e5f parent: 70987:c5b0585624ef parent: 70989:74e9f94d8440 user: Ezio Melotti date: Sun Jun 26 11:38:08 2011 +0300 summary: #11669: merge with 3.2. files: Doc/reference/compound_stmts.rst | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -615,8 +615,9 @@ .. rubric:: Footnotes -.. [#] The exception is propagated to the invocation stack only if there is no - :keyword:`finally` clause that negates the exception. +.. [#] The exception is propagated to the invocation stack unless + there is a :keyword:`finally` clause which happens to raise another + exception. That new exception causes the old one to be lost. .. [#] Currently, control "flows off the end" except in the case of an exception or the execution of a :keyword:`return`, :keyword:`continue`, or -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 11:15:22 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Jun 2011 11:15:22 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Add_pep_number_to_the_body_of_?= =?utf8?q?the_pep=2E?= Message-ID: http://hg.python.org/peps/rev/82ed8b6fb69c changeset: 3890:82ed8b6fb69c user: Raymond Hettinger date: Sun Jun 26 11:15:11 2011 +0200 summary: Add pep number to the body of the pep. files: pep-3153.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/pep-3153.txt b/pep-3153.txt --- a/pep-3153.txt +++ b/pep-3153.txt @@ -1,4 +1,4 @@ -PEP: XXX +PEP: 3153 Title: Asynchronous IO support Version: $Revision$ Last-Modified: $Date$ -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Sun Jun 26 12:39:56 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 12:39:56 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzExMzYzOiBjbGVh?= =?utf8?q?n_up_curses_doc=2E?= Message-ID: http://hg.python.org/cpython/rev/3eb9c31a0b03 changeset: 70991:3eb9c31a0b03 branch: 2.7 parent: 70988:b11e7bc76d07 user: Ezio Melotti date: Sun Jun 26 13:33:46 2011 +0300 summary: #11363: clean up curses doc. files: Doc/library/curses.rst | 174 ++++++++++++++-------------- 1 files changed, 87 insertions(+), 87 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -75,7 +75,7 @@ .. function:: baudrate() - Returns the output speed of the terminal in bits per second. On software + Return the output speed of the terminal in bits per second. On software terminal emulators it will have a fixed high value. Included for historical reasons; in former times, it was used to write output loops for time delays and occasionally to change interfaces depending on the line speed. @@ -88,7 +88,7 @@ .. function:: can_change_color() - Returns true or false, depending on whether the programmer can change the colors + Return ``True`` or ``False``, depending on whether the programmer can change the colors displayed by the terminal. @@ -103,7 +103,7 @@ .. function:: color_content(color_number) - Returns the intensity of the red, green, and blue (RGB) components in the color + Return the intensity of the red, green, and blue (RGB) components in the color *color_number*, which must be between ``0`` and :const:`COLORS`. A 3-tuple is returned, containing the R,G,B values for the given color, which will be between ``0`` (no component) and ``1000`` (maximum amount of component). @@ -111,7 +111,7 @@ .. function:: color_pair(color_number) - Returns the attribute value for displaying text in the specified color. This + Return the attribute value for displaying text in the specified color. This attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`, and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart to this function. @@ -119,7 +119,7 @@ .. function:: curs_set(visibility) - Sets the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, + Set the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, normal, or very visible. If the terminal supports the visibility requested, the previous cursor state is returned; otherwise, an exception is raised. On many terminals, the "visible" mode is an underline cursor and the "very visible" mode @@ -128,7 +128,7 @@ .. function:: def_prog_mode() - Saves the current terminal mode as the "program" mode, the mode when the running + Save the current terminal mode as the "program" mode, the mode when the running program is using curses. (Its counterpart is the "shell" mode, for when the program is not in curses.) Subsequent calls to :func:`reset_prog_mode` will restore this mode. @@ -136,7 +136,7 @@ .. function:: def_shell_mode() - Saves the current terminal mode as the "shell" mode, the mode when the running + Save the current terminal mode as the "shell" mode, the mode when the running program is not using curses. (Its counterpart is the "program" mode, when the program is using curses capabilities.) Subsequent calls to :func:`reset_shell_mode` will restore this mode. @@ -144,7 +144,7 @@ .. function:: delay_output(ms) - Inserts an *ms* millisecond pause in output. + Insert an *ms* millisecond pause in output. .. function:: doupdate() @@ -175,7 +175,7 @@ .. function:: erasechar() - Returns the user's current erase character. Under Unix operating systems this + Return the user's current erase character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. @@ -183,7 +183,7 @@ .. function:: filter() The :func:`.filter` routine, if used, must be called before :func:`initscr` is - called. The effect is that, during those calls, LINES is set to 1; the + called. The effect is that, during those calls, :envvar:`LINES` is set to 1; the capabilities clear, cup, cud, cud1, cuu1, cuu, vpa are disabled; and the home string is set to the value of cr. The effect is that the cursor is confined to the current line, and so are screen updates. This may be used for enabling @@ -209,7 +209,7 @@ method should be call to retrieve the queued mouse event, represented as a 5-tuple ``(id, x, y, z, bstate)``. *id* is an ID value used to distinguish multiple devices, and *x*, *y*, *z* are the event's coordinates. (*z* is - currently unused.). *bstate* is an integer value whose bits will be set to + currently unused.) *bstate* is an integer value whose bits will be set to indicate the type of event, and will be the bitwise OR of one or more of the following constants, where *n* is the button number from 1 to 4: :const:`BUTTONn_PRESSED`, :const:`BUTTONn_RELEASED`, :const:`BUTTONn_CLICKED`, @@ -219,32 +219,32 @@ .. function:: getsyx() - Returns the current coordinates of the virtual screen cursor in y and x. If + Return the current coordinates of the virtual screen cursor in y and x. If leaveok is currently true, then -1,-1 is returned. .. function:: getwin(file) - Reads window related data stored in the file by an earlier :func:`putwin` call. + Read window related data stored in the file by an earlier :func:`putwin` call. The routine then creates and initializes a new window using that data, returning the new window object. .. function:: has_colors() - Returns true if the terminal can display colors; otherwise, it returns false. + Return ``True`` if the terminal can display colors; otherwise, return ``False``. .. function:: has_ic() - Returns true if the terminal has insert- and delete- character capabilities. + Return ``True`` if the terminal has insert- and delete-character capabilities. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. .. function:: has_il() - Returns true if the terminal has insert- and delete-line capabilities, or can + Return ``True`` if the terminal has insert- and delete-line capabilities, or can simulate them using scrolling regions. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. @@ -252,7 +252,7 @@ .. function:: has_key(ch) - Takes a key value *ch*, and returns true if the current terminal type recognizes + Take a key value *ch*, and return ``True`` if the current terminal type recognizes a key with that value. @@ -261,13 +261,13 @@ Used for half-delay mode, which is similar to cbreak mode in that characters typed by the user are immediately available to the program. However, after blocking for *tenths* tenths of seconds, an exception is raised if nothing has - been typed. The value of *tenths* must be a number between 1 and 255. Use + been typed. The value of *tenths* must be a number between ``1`` and ``255``. Use :func:`nocbreak` to leave half-delay mode. .. function:: init_color(color_number, r, g, b) - Changes the definition of a color, taking the number of the color to be changed + Change the definition of a color, taking the number of the color to be changed followed by three RGB values (for the amounts of red, green, and blue components). The value of *color_number* must be between ``0`` and :const:`COLORS`. Each of *r*, *g*, *b*, must be a value between ``0`` and @@ -278,7 +278,7 @@ .. function:: init_pair(pair_number, fg, bg) - Changes the definition of a color-pair. It takes three arguments: the number of + Change the definition of a color-pair. It takes three arguments: the number of the color-pair to be changed, the foreground color number, and the background color number. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot @@ -290,7 +290,7 @@ .. function:: initscr() - Initialize the library. Returns a :class:`WindowObject` which represents the + Initialize the library. Return a :class:`WindowObject` which represents the whole screen. .. note:: @@ -301,7 +301,7 @@ .. function:: isendwin() - Returns true if :func:`endwin` has been called (that is, the curses library has + Return ``True`` if :func:`endwin` has been called (that is, the curses library has been deinitialized). @@ -317,14 +317,14 @@ .. function:: killchar() - Returns the user's current line kill character. Under Unix operating systems + Return the user's current line kill character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. .. function:: longname() - Returns a string containing the terminfo long name field describing the current + Return a string containing the terminfo long name field describing the current terminal. The maximum length of a verbose description is 128 characters. It is defined only after the call to :func:`initscr`. @@ -337,14 +337,14 @@ .. function:: mouseinterval(interval) - Sets the maximum time in milliseconds that can elapse between press and release - events in order for them to be recognized as a click, and returns the previous + Set the maximum time in milliseconds that can elapse between press and release + events in order for them to be recognized as a click, and return the previous interval value. The default value is 200 msec, or one fifth of a second. .. function:: mousemask(mousemask) - Sets the mouse events to be reported, and returns a tuple ``(availmask, + Set the mouse events to be reported, and return a tuple ``(availmask, oldmask)``. *availmask* indicates which of the specified mouse events can be reported; on complete failure it returns 0. *oldmask* is the previous value of the given window's mouse event mask. If this function is never called, no mouse @@ -358,7 +358,7 @@ .. function:: newpad(nlines, ncols) - Creates and returns a pointer to a new pad data structure with the given number + Create and return a pointer to a new pad data structure with the given number of lines and columns. A pad is returned as a window object. A pad is like a window, except that it is not restricted by the screen size, and @@ -368,9 +368,9 @@ echoing of input) do not occur. The :meth:`refresh` and :meth:`noutrefresh` methods of a pad require 6 arguments to specify the part of the pad to be displayed and the location on the screen to be used for the display. The - arguments are pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol; the p + arguments are *pminrow*, *pmincol*, *sminrow*, *smincol*, *smaxrow*, *smaxcol*; the *p* arguments refer to the upper left corner of the pad region to be displayed and - the s arguments define a clipping box on the screen within which the pad region + the *s* arguments define a clipping box on the screen within which the pad region is to be displayed. @@ -412,7 +412,7 @@ .. function:: noqiflush() - When the noqiflush routine is used, normal flush of input and output queues + When the :func:`noqiflush` routine is used, normal flush of input and output queues associated with the INTR, QUIT and SUSP characters will not be done. You may want to call :func:`noqiflush` in a signal handler if you want output to continue as though the interrupt had not occurred, after the handler exits. @@ -425,27 +425,27 @@ .. function:: pair_content(pair_number) - Returns a tuple ``(fg, bg)`` containing the colors for the requested color pair. + Return a tuple ``(fg, bg)`` containing the colors for the requested color pair. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1``. .. function:: pair_number(attr) - Returns the number of the color-pair set by the attribute value *attr*. + Return the number of the color-pair set by the attribute value *attr*. :func:`color_pair` is the counterpart to this function. .. function:: putp(string) - Equivalent to ``tputs(str, 1, putchar)``; emits the value of a specified - terminfo capability for the current terminal. Note that the output of putp + Equivalent to ``tputs(str, 1, putchar)``; emit the value of a specified + terminfo capability for the current terminal. Note that the output of :func:`putp` always goes to standard output. .. function:: qiflush( [flag] ) - If *flag* is false, the effect is the same as calling :func:`noqiflush`. If - *flag* is true, or no argument is provided, the queues will be flushed when + If *flag* is ``False``, the effect is the same as calling :func:`noqiflush`. If + *flag* is ``True``, or no argument is provided, the queues will be flushed when these control characters are read. @@ -458,26 +458,26 @@ .. function:: reset_prog_mode() - Restores the terminal to "program" mode, as previously saved by + Restore the terminal to "program" mode, as previously saved by :func:`def_prog_mode`. .. function:: reset_shell_mode() - Restores the terminal to "shell" mode, as previously saved by + Restore the terminal to "shell" mode, as previously saved by :func:`def_shell_mode`. .. function:: setsyx(y, x) - Sets the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then + Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then leaveok is set. .. function:: setupterm([termstr, fd]) - Initializes the terminal. *termstr* is a string giving the terminal name; if - omitted, the value of the TERM environment variable will be used. *fd* is the + Initialize the terminal. *termstr* is a string giving the terminal name; if + omitted, the value of the :envvar:`TERM` environment variable will be used. *fd* is the file descriptor to which any initialization sequences will be sent; if not supplied, the file descriptor for ``sys.stdout`` will be used. @@ -497,19 +497,19 @@ .. function:: termattrs() - Returns a logical OR of all video attributes supported by the terminal. This + Return a logical OR of all video attributes supported by the terminal. This information is useful when a curses program needs complete control over the appearance of the screen. .. function:: termname() - Returns the value of the environment variable TERM, truncated to 14 characters. + Return the value of the environment variable :envvar:`TERM`, truncated to 14 characters. .. function:: tigetflag(capname) - Returns the value of the Boolean capability corresponding to the terminfo + Return the value of the Boolean capability corresponding to the terminfo capability name *capname*. The value ``-1`` is returned if *capname* is not a Boolean capability, or ``0`` if it is canceled or absent from the terminal description. @@ -517,7 +517,7 @@ .. function:: tigetnum(capname) - Returns the value of the numeric capability corresponding to the terminfo + Return the value of the numeric capability corresponding to the terminfo capability name *capname*. The value ``-2`` is returned if *capname* is not a numeric capability, or ``-1`` if it is canceled or absent from the terminal description. @@ -525,22 +525,22 @@ .. function:: tigetstr(capname) - Returns the value of the string capability corresponding to the terminfo + Return the value of the string capability corresponding to the terminfo capability name *capname*. ``None`` is returned if *capname* is not a string capability, or is canceled or absent from the terminal description. .. function:: tparm(str[,...]) - Instantiates the string *str* with the supplied parameters, where *str* should - be a parameterized string obtained from the terminfo database. E.g. - ``tparm(tigetstr("cup"), 5, 3)`` could result in ``'\033[6;4H'``, the exact + Instantiate the string *str* with the supplied parameters, where *str* should + be a parameterized string obtained from the terminfo database. E.g. + ``tparm(tigetstr("cup"), 5, 3)`` could result in ``'\033[6;4H'``, the exact result depending on terminal type. .. function:: typeahead(fd) - Specifies that the file descriptor *fd* be used for typeahead checking. If *fd* + Specify that the file descriptor *fd* be used for typeahead checking. If *fd* is ``-1``, then no typeahead checking is done. The curses library does "line-breakout optimization" by looking for typeahead @@ -552,7 +552,7 @@ .. function:: unctrl(ch) - Returns a string which is a printable representation of the character *ch*. + Return a string which is a printable representation of the character *ch*. Control characters are displayed as a caret followed by the character, for example as ``^C``. Printing characters are left as they are. @@ -575,7 +575,7 @@ .. function:: use_env(flag) If used, this function should be called before :func:`initscr` or newterm are - called. When *flag* is false, the values of lines and columns specified in the + called. When *flag* is ``False``, the values of lines and columns specified in the terminfo database will be used, even if environment variables :envvar:`LINES` and :envvar:`COLUMNS` (used by default) are set, or if curses is running in a window (in which case default behavior would be to use the window size if @@ -659,7 +659,7 @@ .. method:: window.bkgd(ch[, attr]) - Sets the background property of the window to the character *ch*, with + Set the background property of the window to the character *ch*, with attributes *attr*. The change is then applied to every character position in that window: @@ -672,7 +672,7 @@ .. method:: window.bkgdset(ch[, attr]) - Sets the window's background. A window's background consists of a character and + Set the window's background. A window's background consists of a character and any combination of attributes. The attribute part of the background is combined (OR'ed) with all non-blank characters that are written into the window. Both the character and attribute parts of the background are combined with the blank @@ -717,12 +717,12 @@ .. method:: window.box([vertch, horch]) Similar to :meth:`border`, but both *ls* and *rs* are *vertch* and both *ts* and - bs are *horch*. The default corner characters are always used by this function. + *bs* are *horch*. The default corner characters are always used by this function. .. method:: window.chgat([y, x, ] [num,] attr) - Sets the attributes of *num* characters at the current cursor position, or at + Set the attributes of *num* characters at the current cursor position, or at position ``(y, x)`` if supplied. If no value of *num* is given or *num* = -1, the attribute will be set on all the characters to the end of the line. This function does not move the cursor. The changed line will be touched using the @@ -732,7 +732,7 @@ .. method:: window.clear() - Like :meth:`erase`, but also causes the whole window to be repainted upon next + Like :meth:`erase`, but also cause the whole window to be repainted upon next call to :meth:`refresh`. @@ -755,7 +755,7 @@ .. method:: window.cursyncup() - Updates the current cursor position of all the ancestors of the window to + Update the current cursor position of all the ancestors of the window to reflect the current cursor position of the window. @@ -766,14 +766,14 @@ .. method:: window.deleteln() - Delete the line under the cursor. All following lines are moved up by 1 line. + Delete the line under the cursor. All following lines are moved up by one line. .. method:: window.derwin([nlines, ncols,] begin_y, begin_x) An abbreviation for "derive window", :meth:`derwin` is the same as calling :meth:`subwin`, except that *begin_y* and *begin_x* are relative to the origin - of the window, rather than relative to the entire screen. Returns a window + of the window, rather than relative to the entire screen. Return a window object for the derived window. @@ -785,8 +785,8 @@ .. method:: window.enclose(y, x) - Tests whether the given pair of screen-relative character-cell coordinates are - enclosed by the given window, returning true or false. It is useful for + Test whether the given pair of screen-relative character-cell coordinates are + enclosed by the given window, returning ``True`` or ``False``. It is useful for determining what subset of the screen windows enclose the location of a mouse event. @@ -823,8 +823,8 @@ .. method:: window.getparyx() - Returns the beginning coordinates of this window relative to its parent window - into two integer variables y and x. Returns ``-1,-1`` if this window has no + Return the beginning coordinates of this window relative to its parent window + into two integer variables y and x. Return ``-1, -1`` if this window has no parent. @@ -847,8 +847,8 @@ .. method:: window.idcok(flag) - If *flag* is false, curses no longer considers using the hardware insert/delete - character feature of the terminal; if *flag* is true, use of character insertion + If *flag* is ``False``, curses no longer considers using the hardware insert/delete + character feature of the terminal; if *flag* is ``True``, use of character insertion and deletion is enabled. When curses is first initialized, use of character insert/delete is enabled by default. @@ -861,7 +861,7 @@ .. method:: window.immedok(flag) - If *flag* is true, any change in the window image automatically causes the + If *flag* is ``True``, any change in the window image automatically causes the window to be refreshed; you no longer have to call :meth:`refresh` yourself. However, it may degrade performance considerably, due to repeated calls to wrefresh. This option is disabled by default. @@ -881,7 +881,7 @@ .. method:: window.insdelln(nlines) - Inserts *nlines* lines into the specified window above the current line. The + Insert *nlines* lines into the specified window above the current line. The *nlines* bottom lines are lost. For negative *nlines*, delete *nlines* lines starting with the one under the cursor, and move the remaining lines up. The bottom *nlines* lines are cleared. The current cursor position remains the @@ -890,7 +890,7 @@ .. method:: window.insertln() - Insert a blank line under the cursor. All following lines are moved down by 1 + Insert a blank line under the cursor. All following lines are moved down by one line. @@ -913,23 +913,23 @@ .. method:: window.instr([y, x] [, n]) - Returns a string of characters, extracted from the window starting at the + Return a string of characters, extracted from the window starting at the current cursor position, or at *y*, *x* if specified. Attributes are stripped - from the characters. If *n* is specified, :meth:`instr` returns return a string + from the characters. If *n* is specified, :meth:`instr` returns a string at most *n* characters long (exclusive of the trailing NUL). .. method:: window.is_linetouched(line) - Returns true if the specified line was modified since the last call to - :meth:`refresh`; otherwise returns false. Raises a :exc:`curses.error` + Return ``True`` if the specified line was modified since the last call to + :meth:`refresh`; otherwise return ``False``. Raise a :exc:`curses.error` exception if *line* is not valid for the given window. .. method:: window.is_wintouched() - Returns true if the specified window was modified since the last call to - :meth:`refresh`; otherwise returns false. + Return ``True`` if the specified window was modified since the last call to + :meth:`refresh`; otherwise return ``False``. .. method:: window.keypad(yes) @@ -955,7 +955,7 @@ .. method:: window.mvderwin(y, x) - Moves the window inside its parent window. The screen-relative parameters of + Move the window inside its parent window. The screen-relative parameters of the window are not changed. This routine is used to display different parts of the parent window at the same physical position on the screen. @@ -1013,19 +1013,19 @@ .. method:: window.putwin(file) - Writes all data associated with the window into the provided file object. This + Write all data associated with the window into the provided file object. This information can be later retrieved using the :func:`getwin` function. .. method:: window.redrawln(beg, num) - Indicates that the *num* screen lines, starting at line *beg*, are corrupted and + Indicate that the *num* screen lines, starting at line *beg*, are corrupted and should be completely redrawn on the next :meth:`refresh` call. .. method:: window.redrawwin() - Touches the entire window, causing it to be completely redrawn on the next + Touch the entire window, causing it to be completely redrawn on the next :meth:`refresh` call. @@ -1053,7 +1053,7 @@ .. method:: window.scrollok(flag) - Controls what happens when the cursor of a window is moved off the edge of the + Control what happens when the cursor of a window is moved off the edge of the window or scrolling region, either as a result of a newline action on the bottom line, or typing the last character of the last line. If *flag* is false, the cursor is left on the bottom line. If *flag* is true, the window is scrolled up @@ -1095,26 +1095,26 @@ .. method:: window.syncdown() - Touches each location in the window that has been touched in any of its ancestor + Touch each location in the window that has been touched in any of its ancestor windows. This routine is called by :meth:`refresh`, so it should almost never be necessary to call it manually. .. method:: window.syncok(flag) - If called with *flag* set to true, then :meth:`syncup` is called automatically + If called with *flag* set to ``True``, then :meth:`syncup` is called automatically whenever there is a change in the window. .. method:: window.syncup() - Touches all locations in ancestors of the window that have been changed in the + Touch all locations in ancestors of the window that have been changed in the window. .. method:: window.timeout(delay) - Sets blocking or non-blocking read behavior for the window. If *delay* is + Set blocking or non-blocking read behavior for the window. If *delay* is negative, blocking read is used (which will wait indefinitely for input). If *delay* is zero, then non-blocking read is used, and -1 will be returned by :meth:`getch` if no input is waiting. If *delay* is positive, then @@ -1137,7 +1137,7 @@ .. method:: window.untouchwin() - Marks all lines in the window as unchanged since the last call to + Mark all lines in the window as unchanged since the last call to :meth:`refresh`. @@ -1662,7 +1662,7 @@ .. method:: gather() - This method returns the window contents as a string; whether blanks in the + Return the window contents as a string; whether blanks in the window are included is affected by the :attr:`stripspaces` member. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 12:39:57 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 12:39:57 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogIzExMzYzOiBhZGQg?= =?utf8?q?missing_functions_from_curses_doc=2E_Patch_by_Sandro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/3dc602b1f4a2 changeset: 70992:3dc602b1f4a2 branch: 2.7 user: Ezio Melotti date: Sun Jun 26 13:34:56 2011 +0300 summary: #11363: add missing functions from curses doc. Patch by Sandro Tosi. files: Doc/library/curses.rst | 48 ++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -299,6 +299,12 @@ cause the interpreter to exit. +.. function:: is_term_resized(nlines, ncols) + + Return ``True`` if :func:`resize_term` would modify the window structure, + ``False`` otherwise. + + .. function:: isendwin() Return ``True`` if :func:`endwin` has been called (that is, the curses library has @@ -468,6 +474,35 @@ :func:`def_shell_mode`. +.. function:: resetty() + + Restore the state of the terminal modes to what it was at the last call to + :func:`savetty`. + + +.. function:: resize_term(nlines, ncols) + + Backend function used by :func:`resizeterm`, performing most of the work; + when resizing the windows, :func:`resize_term` blank-fills the areas that are + extended. The calling application should fill in these areas with + appropriate data. The :func:`resize_term` function attempts to resize all + windows. However, due to the calling convention of pads, it is not possible + to resize these without additional interaction with the application. + + +.. function:: resizeterm(nlines, ncols) + + Resize the standard and current windows to the specified dimensions, and + adjusts other bookkeeping data used by the curses library that record the + window dimensions (in particular the SIGWINCH handler). + + +.. function:: savetty() + + Save the current state of the terminal modes in a buffer, usable by + :func:`resetty`. + + .. function:: setsyx(y, x) Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then @@ -801,6 +836,11 @@ Return a tuple ``(y, x)`` of co-ordinates of upper-left corner. +.. method:: window.getbkgd() + + Return the given window's current background character/attribute pair. + + .. method:: window.getch([y, x]) Get a character. Note that the integer returned does *not* have to be in ASCII @@ -1046,6 +1086,14 @@ *sminrow*, or *smincol* are treated as if they were zero. +.. method:: window.resize(nlines, ncols) + + Reallocate storage for a curses window to adjust its dimensions to the + specified values. If either dimension is larger than the current values, the + window's data is filled with blanks that have the current background + rendition (as set by :meth:`bkgdset`) merged into them. + + .. method:: window.scroll([lines=1]) Scroll the screen or scrolling region upward by *lines* lines. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 12:39:57 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 12:39:57 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExMzYzOiBjbGVh?= =?utf8?q?n_up_curses_doc=2E?= Message-ID: http://hg.python.org/cpython/rev/bb27baa1124a changeset: 70993:bb27baa1124a branch: 3.2 parent: 70989:74e9f94d8440 user: Ezio Melotti date: Sun Jun 26 13:38:11 2011 +0300 summary: #11363: clean up curses doc. files: Doc/library/curses.rst | 174 ++++++++++++++-------------- 1 files changed, 87 insertions(+), 87 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -72,7 +72,7 @@ .. function:: baudrate() - Returns the output speed of the terminal in bits per second. On software + Return the output speed of the terminal in bits per second. On software terminal emulators it will have a fixed high value. Included for historical reasons; in former times, it was used to write output loops for time delays and occasionally to change interfaces depending on the line speed. @@ -85,7 +85,7 @@ .. function:: can_change_color() - Returns true or false, depending on whether the programmer can change the colors + Return ``True`` or ``False``, depending on whether the programmer can change the colors displayed by the terminal. @@ -100,7 +100,7 @@ .. function:: color_content(color_number) - Returns the intensity of the red, green, and blue (RGB) components in the color + Return the intensity of the red, green, and blue (RGB) components in the color *color_number*, which must be between ``0`` and :const:`COLORS`. A 3-tuple is returned, containing the R,G,B values for the given color, which will be between ``0`` (no component) and ``1000`` (maximum amount of component). @@ -108,7 +108,7 @@ .. function:: color_pair(color_number) - Returns the attribute value for displaying text in the specified color. This + Return the attribute value for displaying text in the specified color. This attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`, and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart to this function. @@ -116,7 +116,7 @@ .. function:: curs_set(visibility) - Sets the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, + Set the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, normal, or very visible. If the terminal supports the visibility requested, the previous cursor state is returned; otherwise, an exception is raised. On many terminals, the "visible" mode is an underline cursor and the "very visible" mode @@ -125,7 +125,7 @@ .. function:: def_prog_mode() - Saves the current terminal mode as the "program" mode, the mode when the running + Save the current terminal mode as the "program" mode, the mode when the running program is using curses. (Its counterpart is the "shell" mode, for when the program is not in curses.) Subsequent calls to :func:`reset_prog_mode` will restore this mode. @@ -133,7 +133,7 @@ .. function:: def_shell_mode() - Saves the current terminal mode as the "shell" mode, the mode when the running + Save the current terminal mode as the "shell" mode, the mode when the running program is not using curses. (Its counterpart is the "program" mode, when the program is using curses capabilities.) Subsequent calls to :func:`reset_shell_mode` will restore this mode. @@ -141,7 +141,7 @@ .. function:: delay_output(ms) - Inserts an *ms* millisecond pause in output. + Insert an *ms* millisecond pause in output. .. function:: doupdate() @@ -172,7 +172,7 @@ .. function:: erasechar() - Returns the user's current erase character. Under Unix operating systems this + Return the user's current erase character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. @@ -180,7 +180,7 @@ .. function:: filter() The :func:`.filter` routine, if used, must be called before :func:`initscr` is - called. The effect is that, during those calls, LINES is set to 1; the + called. The effect is that, during those calls, :envvar:`LINES` is set to 1; the capabilities clear, cup, cud, cud1, cuu1, cuu, vpa are disabled; and the home string is set to the value of cr. The effect is that the cursor is confined to the current line, and so are screen updates. This may be used for enabling @@ -206,7 +206,7 @@ method should be call to retrieve the queued mouse event, represented as a 5-tuple ``(id, x, y, z, bstate)``. *id* is an ID value used to distinguish multiple devices, and *x*, *y*, *z* are the event's coordinates. (*z* is - currently unused.). *bstate* is an integer value whose bits will be set to + currently unused.) *bstate* is an integer value whose bits will be set to indicate the type of event, and will be the bitwise OR of one or more of the following constants, where *n* is the button number from 1 to 4: :const:`BUTTONn_PRESSED`, :const:`BUTTONn_RELEASED`, :const:`BUTTONn_CLICKED`, @@ -216,32 +216,32 @@ .. function:: getsyx() - Returns the current coordinates of the virtual screen cursor in y and x. If + Return the current coordinates of the virtual screen cursor in y and x. If leaveok is currently true, then -1,-1 is returned. .. function:: getwin(file) - Reads window related data stored in the file by an earlier :func:`putwin` call. + Read window related data stored in the file by an earlier :func:`putwin` call. The routine then creates and initializes a new window using that data, returning the new window object. .. function:: has_colors() - Returns true if the terminal can display colors; otherwise, it returns false. + Return ``True`` if the terminal can display colors; otherwise, return ``False``. .. function:: has_ic() - Returns true if the terminal has insert- and delete- character capabilities. + Return ``True`` if the terminal has insert- and delete-character capabilities. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. .. function:: has_il() - Returns true if the terminal has insert- and delete-line capabilities, or can + Return ``True`` if the terminal has insert- and delete-line capabilities, or can simulate them using scrolling regions. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. @@ -249,7 +249,7 @@ .. function:: has_key(ch) - Takes a key value *ch*, and returns true if the current terminal type recognizes + Take a key value *ch*, and return ``True`` if the current terminal type recognizes a key with that value. @@ -258,13 +258,13 @@ Used for half-delay mode, which is similar to cbreak mode in that characters typed by the user are immediately available to the program. However, after blocking for *tenths* tenths of seconds, an exception is raised if nothing has - been typed. The value of *tenths* must be a number between 1 and 255. Use + been typed. The value of *tenths* must be a number between ``1`` and ``255``. Use :func:`nocbreak` to leave half-delay mode. .. function:: init_color(color_number, r, g, b) - Changes the definition of a color, taking the number of the color to be changed + Change the definition of a color, taking the number of the color to be changed followed by three RGB values (for the amounts of red, green, and blue components). The value of *color_number* must be between ``0`` and :const:`COLORS`. Each of *r*, *g*, *b*, must be a value between ``0`` and @@ -275,7 +275,7 @@ .. function:: init_pair(pair_number, fg, bg) - Changes the definition of a color-pair. It takes three arguments: the number of + Change the definition of a color-pair. It takes three arguments: the number of the color-pair to be changed, the foreground color number, and the background color number. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot @@ -287,7 +287,7 @@ .. function:: initscr() - Initialize the library. Returns a :class:`WindowObject` which represents the + Initialize the library. Return a :class:`WindowObject` which represents the whole screen. .. note:: @@ -298,7 +298,7 @@ .. function:: isendwin() - Returns true if :func:`endwin` has been called (that is, the curses library has + Return ``True`` if :func:`endwin` has been called (that is, the curses library has been deinitialized). @@ -314,14 +314,14 @@ .. function:: killchar() - Returns the user's current line kill character. Under Unix operating systems + Return the user's current line kill character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. .. function:: longname() - Returns a string containing the terminfo long name field describing the current + Return a string containing the terminfo long name field describing the current terminal. The maximum length of a verbose description is 128 characters. It is defined only after the call to :func:`initscr`. @@ -334,14 +334,14 @@ .. function:: mouseinterval(interval) - Sets the maximum time in milliseconds that can elapse between press and release - events in order for them to be recognized as a click, and returns the previous + Set the maximum time in milliseconds that can elapse between press and release + events in order for them to be recognized as a click, and return the previous interval value. The default value is 200 msec, or one fifth of a second. .. function:: mousemask(mousemask) - Sets the mouse events to be reported, and returns a tuple ``(availmask, + Set the mouse events to be reported, and return a tuple ``(availmask, oldmask)``. *availmask* indicates which of the specified mouse events can be reported; on complete failure it returns 0. *oldmask* is the previous value of the given window's mouse event mask. If this function is never called, no mouse @@ -355,7 +355,7 @@ .. function:: newpad(nlines, ncols) - Creates and returns a pointer to a new pad data structure with the given number + Create and return a pointer to a new pad data structure with the given number of lines and columns. A pad is returned as a window object. A pad is like a window, except that it is not restricted by the screen size, and @@ -365,9 +365,9 @@ echoing of input) do not occur. The :meth:`refresh` and :meth:`noutrefresh` methods of a pad require 6 arguments to specify the part of the pad to be displayed and the location on the screen to be used for the display. The - arguments are pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol; the p + arguments are *pminrow*, *pmincol*, *sminrow*, *smincol*, *smaxrow*, *smaxcol*; the *p* arguments refer to the upper left corner of the pad region to be displayed and - the s arguments define a clipping box on the screen within which the pad region + the *s* arguments define a clipping box on the screen within which the pad region is to be displayed. @@ -409,7 +409,7 @@ .. function:: noqiflush() - When the noqiflush routine is used, normal flush of input and output queues + When the :func:`noqiflush` routine is used, normal flush of input and output queues associated with the INTR, QUIT and SUSP characters will not be done. You may want to call :func:`noqiflush` in a signal handler if you want output to continue as though the interrupt had not occurred, after the handler exits. @@ -422,27 +422,27 @@ .. function:: pair_content(pair_number) - Returns a tuple ``(fg, bg)`` containing the colors for the requested color pair. + Return a tuple ``(fg, bg)`` containing the colors for the requested color pair. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1``. .. function:: pair_number(attr) - Returns the number of the color-pair set by the attribute value *attr*. + Return the number of the color-pair set by the attribute value *attr*. :func:`color_pair` is the counterpart to this function. .. function:: putp(string) - Equivalent to ``tputs(str, 1, putchar)``; emits the value of a specified - terminfo capability for the current terminal. Note that the output of putp + Equivalent to ``tputs(str, 1, putchar)``; emit the value of a specified + terminfo capability for the current terminal. Note that the output of :func:`putp` always goes to standard output. .. function:: qiflush( [flag] ) - If *flag* is false, the effect is the same as calling :func:`noqiflush`. If - *flag* is true, or no argument is provided, the queues will be flushed when + If *flag* is ``False``, the effect is the same as calling :func:`noqiflush`. If + *flag* is ``True``, or no argument is provided, the queues will be flushed when these control characters are read. @@ -455,26 +455,26 @@ .. function:: reset_prog_mode() - Restores the terminal to "program" mode, as previously saved by + Restore the terminal to "program" mode, as previously saved by :func:`def_prog_mode`. .. function:: reset_shell_mode() - Restores the terminal to "shell" mode, as previously saved by + Restore the terminal to "shell" mode, as previously saved by :func:`def_shell_mode`. .. function:: setsyx(y, x) - Sets the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then + Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then leaveok is set. .. function:: setupterm([termstr, fd]) - Initializes the terminal. *termstr* is a string giving the terminal name; if - omitted, the value of the TERM environment variable will be used. *fd* is the + Initialize the terminal. *termstr* is a string giving the terminal name; if + omitted, the value of the :envvar:`TERM` environment variable will be used. *fd* is the file descriptor to which any initialization sequences will be sent; if not supplied, the file descriptor for ``sys.stdout`` will be used. @@ -494,19 +494,19 @@ .. function:: termattrs() - Returns a logical OR of all video attributes supported by the terminal. This + Return a logical OR of all video attributes supported by the terminal. This information is useful when a curses program needs complete control over the appearance of the screen. .. function:: termname() - Returns the value of the environment variable TERM, truncated to 14 characters. + Return the value of the environment variable :envvar:`TERM`, truncated to 14 characters. .. function:: tigetflag(capname) - Returns the value of the Boolean capability corresponding to the terminfo + Return the value of the Boolean capability corresponding to the terminfo capability name *capname*. The value ``-1`` is returned if *capname* is not a Boolean capability, or ``0`` if it is canceled or absent from the terminal description. @@ -514,7 +514,7 @@ .. function:: tigetnum(capname) - Returns the value of the numeric capability corresponding to the terminfo + Return the value of the numeric capability corresponding to the terminfo capability name *capname*. The value ``-2`` is returned if *capname* is not a numeric capability, or ``-1`` if it is canceled or absent from the terminal description. @@ -522,22 +522,22 @@ .. function:: tigetstr(capname) - Returns the value of the string capability corresponding to the terminfo + Return the value of the string capability corresponding to the terminfo capability name *capname*. ``None`` is returned if *capname* is not a string capability, or is canceled or absent from the terminal description. .. function:: tparm(str[, ...]) - Instantiates the string *str* with the supplied parameters, where *str* should - be a parameterized string obtained from the terminfo database. E.g. - ``tparm(tigetstr("cup"), 5, 3)`` could result in ``'\033[6;4H'``, the exact + Instantiate the string *str* with the supplied parameters, where *str* should + be a parameterized string obtained from the terminfo database. E.g. + ``tparm(tigetstr("cup"), 5, 3)`` could result in x``'\033[6;4H'``, the exact result depending on terminal type. .. function:: typeahead(fd) - Specifies that the file descriptor *fd* be used for typeahead checking. If *fd* + Specify that the file descriptor *fd* be used for typeahead checking. If *fd* is ``-1``, then no typeahead checking is done. The curses library does "line-breakout optimization" by looking for typeahead @@ -549,7 +549,7 @@ .. function:: unctrl(ch) - Returns a string which is a printable representation of the character *ch*. + Return a string which is a printable representation of the character *ch*. Control characters are displayed as a caret followed by the character, for example as ``^C``. Printing characters are left as they are. @@ -572,7 +572,7 @@ .. function:: use_env(flag) If used, this function should be called before :func:`initscr` or newterm are - called. When *flag* is false, the values of lines and columns specified in the + called. When *flag* is ``False``, the values of lines and columns specified in the terminfo database will be used, even if environment variables :envvar:`LINES` and :envvar:`COLUMNS` (used by default) are set, or if curses is running in a window (in which case default behavior would be to use the window size if @@ -656,7 +656,7 @@ .. method:: window.bkgd(ch[, attr]) - Sets the background property of the window to the character *ch*, with + Set the background property of the window to the character *ch*, with attributes *attr*. The change is then applied to every character position in that window: @@ -669,7 +669,7 @@ .. method:: window.bkgdset(ch[, attr]) - Sets the window's background. A window's background consists of a character and + Set the window's background. A window's background consists of a character and any combination of attributes. The attribute part of the background is combined (OR'ed) with all non-blank characters that are written into the window. Both the character and attribute parts of the background are combined with the blank @@ -714,12 +714,12 @@ .. method:: window.box([vertch, horch]) Similar to :meth:`border`, but both *ls* and *rs* are *vertch* and both *ts* and - bs are *horch*. The default corner characters are always used by this function. + *bs* are *horch*. The default corner characters are always used by this function. .. method:: window.chgat([y, x, ] [num,] attr) - Sets the attributes of *num* characters at the current cursor position, or at + Set the attributes of *num* characters at the current cursor position, or at position ``(y, x)`` if supplied. If no value of *num* is given or *num* = -1, the attribute will be set on all the characters to the end of the line. This function does not move the cursor. The changed line will be touched using the @@ -729,7 +729,7 @@ .. method:: window.clear() - Like :meth:`erase`, but also causes the whole window to be repainted upon next + Like :meth:`erase`, but also cause the whole window to be repainted upon next call to :meth:`refresh`. @@ -752,7 +752,7 @@ .. method:: window.cursyncup() - Updates the current cursor position of all the ancestors of the window to + Update the current cursor position of all the ancestors of the window to reflect the current cursor position of the window. @@ -763,14 +763,14 @@ .. method:: window.deleteln() - Delete the line under the cursor. All following lines are moved up by 1 line. + Delete the line under the cursor. All following lines are moved up by one line. .. method:: window.derwin([nlines, ncols,] begin_y, begin_x) An abbreviation for "derive window", :meth:`derwin` is the same as calling :meth:`subwin`, except that *begin_y* and *begin_x* are relative to the origin - of the window, rather than relative to the entire screen. Returns a window + of the window, rather than relative to the entire screen. Return a window object for the derived window. @@ -782,8 +782,8 @@ .. method:: window.enclose(y, x) - Tests whether the given pair of screen-relative character-cell coordinates are - enclosed by the given window, returning true or false. It is useful for + Test whether the given pair of screen-relative character-cell coordinates are + enclosed by the given window, returning ``True`` or ``False``. It is useful for determining what subset of the screen windows enclose the location of a mouse event. @@ -820,8 +820,8 @@ .. method:: window.getparyx() - Returns the beginning coordinates of this window relative to its parent window - into two integer variables y and x. Returns ``-1,-1`` if this window has no + Return the beginning coordinates of this window relative to its parent window + into two integer variables y and x. Return ``-1, -1`` if this window has no parent. @@ -844,8 +844,8 @@ .. method:: window.idcok(flag) - If *flag* is false, curses no longer considers using the hardware insert/delete - character feature of the terminal; if *flag* is true, use of character insertion + If *flag* is ``False``, curses no longer considers using the hardware insert/delete + character feature of the terminal; if *flag* is ``True``, use of character insertion and deletion is enabled. When curses is first initialized, use of character insert/delete is enabled by default. @@ -858,7 +858,7 @@ .. method:: window.immedok(flag) - If *flag* is true, any change in the window image automatically causes the + If *flag* is ``True``, any change in the window image automatically causes the window to be refreshed; you no longer have to call :meth:`refresh` yourself. However, it may degrade performance considerably, due to repeated calls to wrefresh. This option is disabled by default. @@ -878,7 +878,7 @@ .. method:: window.insdelln(nlines) - Inserts *nlines* lines into the specified window above the current line. The + Insert *nlines* lines into the specified window above the current line. The *nlines* bottom lines are lost. For negative *nlines*, delete *nlines* lines starting with the one under the cursor, and move the remaining lines up. The bottom *nlines* lines are cleared. The current cursor position remains the @@ -887,7 +887,7 @@ .. method:: window.insertln() - Insert a blank line under the cursor. All following lines are moved down by 1 + Insert a blank line under the cursor. All following lines are moved down by one line. @@ -910,23 +910,23 @@ .. method:: window.instr([y, x] [, n]) - Returns a string of characters, extracted from the window starting at the + Return a string of characters, extracted from the window starting at the current cursor position, or at *y*, *x* if specified. Attributes are stripped - from the characters. If *n* is specified, :meth:`instr` returns return a string + from the characters. If *n* is specified, :meth:`instr` returns a string at most *n* characters long (exclusive of the trailing NUL). .. method:: window.is_linetouched(line) - Returns true if the specified line was modified since the last call to - :meth:`refresh`; otherwise returns false. Raises a :exc:`curses.error` + Return ``True`` if the specified line was modified since the last call to + :meth:`refresh`; otherwise return ``False``. Raise a :exc:`curses.error` exception if *line* is not valid for the given window. .. method:: window.is_wintouched() - Returns true if the specified window was modified since the last call to - :meth:`refresh`; otherwise returns false. + Return ``True`` if the specified window was modified since the last call to + :meth:`refresh`; otherwise return ``False``. .. method:: window.keypad(yes) @@ -952,7 +952,7 @@ .. method:: window.mvderwin(y, x) - Moves the window inside its parent window. The screen-relative parameters of + Move the window inside its parent window. The screen-relative parameters of the window are not changed. This routine is used to display different parts of the parent window at the same physical position on the screen. @@ -1010,19 +1010,19 @@ .. method:: window.putwin(file) - Writes all data associated with the window into the provided file object. This + Write all data associated with the window into the provided file object. This information can be later retrieved using the :func:`getwin` function. .. method:: window.redrawln(beg, num) - Indicates that the *num* screen lines, starting at line *beg*, are corrupted and + Indicate that the *num* screen lines, starting at line *beg*, are corrupted and should be completely redrawn on the next :meth:`refresh` call. .. method:: window.redrawwin() - Touches the entire window, causing it to be completely redrawn on the next + Touch the entire window, causing it to be completely redrawn on the next :meth:`refresh` call. @@ -1050,7 +1050,7 @@ .. method:: window.scrollok(flag) - Controls what happens when the cursor of a window is moved off the edge of the + Control what happens when the cursor of a window is moved off the edge of the window or scrolling region, either as a result of a newline action on the bottom line, or typing the last character of the last line. If *flag* is false, the cursor is left on the bottom line. If *flag* is true, the window is scrolled up @@ -1092,26 +1092,26 @@ .. method:: window.syncdown() - Touches each location in the window that has been touched in any of its ancestor + Touch each location in the window that has been touched in any of its ancestor windows. This routine is called by :meth:`refresh`, so it should almost never be necessary to call it manually. .. method:: window.syncok(flag) - If called with *flag* set to true, then :meth:`syncup` is called automatically + If called with *flag* set to ``True``, then :meth:`syncup` is called automatically whenever there is a change in the window. .. method:: window.syncup() - Touches all locations in ancestors of the window that have been changed in the + Touch all locations in ancestors of the window that have been changed in the window. .. method:: window.timeout(delay) - Sets blocking or non-blocking read behavior for the window. If *delay* is + Set blocking or non-blocking read behavior for the window. If *delay* is negative, blocking read is used (which will wait indefinitely for input). If *delay* is zero, then non-blocking read is used, and -1 will be returned by :meth:`getch` if no input is waiting. If *delay* is positive, then @@ -1134,7 +1134,7 @@ .. method:: window.untouchwin() - Marks all lines in the window as unchanged since the last call to + Mark all lines in the window as unchanged since the last call to :meth:`refresh`. @@ -1657,7 +1657,7 @@ .. method:: gather() - This method returns the window contents as a string; whether blanks in the + Return the window contents as a string; whether blanks in the window are included is affected by the :attr:`stripspaces` member. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 12:39:58 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 12:39:58 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogIzExMzYzOiBhZGQg?= =?utf8?q?missing_functions_from_curses_doc=2E_Patch_by_Sandro_Tosi=2E?= Message-ID: http://hg.python.org/cpython/rev/f852e2d556af changeset: 70994:f852e2d556af branch: 3.2 user: Ezio Melotti date: Sun Jun 26 13:34:56 2011 +0300 summary: #11363: add missing functions from curses doc. Patch by Sandro Tosi. files: Doc/library/curses.rst | 48 ++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -296,6 +296,12 @@ cause the interpreter to exit. +.. function:: is_term_resized(nlines, ncols) + + Return ``True`` if :func:`resize_term` would modify the window structure, + ``False`` otherwise. + + .. function:: isendwin() Return ``True`` if :func:`endwin` has been called (that is, the curses library has @@ -465,6 +471,35 @@ :func:`def_shell_mode`. +.. function:: resetty() + + Restore the state of the terminal modes to what it was at the last call to + :func:`savetty`. + + +.. function:: resize_term(nlines, ncols) + + Backend function used by :func:`resizeterm`, performing most of the work; + when resizing the windows, :func:`resize_term` blank-fills the areas that are + extended. The calling application should fill in these areas with + appropriate data. The :func:`resize_term` function attempts to resize all + windows. However, due to the calling convention of pads, it is not possible + to resize these without additional interaction with the application. + + +.. function:: resizeterm(nlines, ncols) + + Resize the standard and current windows to the specified dimensions, and + adjusts other bookkeeping data used by the curses library that record the + window dimensions (in particular the SIGWINCH handler). + + +.. function:: savetty() + + Save the current state of the terminal modes in a buffer, usable by + :func:`resetty`. + + .. function:: setsyx(y, x) Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then @@ -798,6 +833,11 @@ Return a tuple ``(y, x)`` of co-ordinates of upper-left corner. +.. method:: window.getbkgd() + + Return the given window's current background character/attribute pair. + + .. method:: window.getch([y, x]) Get a character. Note that the integer returned does *not* have to be in ASCII @@ -1043,6 +1083,14 @@ *sminrow*, or *smincol* are treated as if they were zero. +.. method:: window.resize(nlines, ncols) + + Reallocate storage for a curses window to adjust its dimensions to the + specified values. If either dimension is larger than the current values, the + window's data is filled with blanks that have the current background + rendition (as set by :meth:`bkgdset`) merged into them. + + .. method:: window.scroll([lines=1]) Scroll the screen or scrolling region upward by *lines* lines. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 12:39:59 2011 From: python-checkins at python.org (ezio.melotti) Date: Sun, 26 Jun 2011 12:39:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=2311363=3A_merge_with_3=2E2=2E?= Message-ID: http://hg.python.org/cpython/rev/b879bad40154 changeset: 70995:b879bad40154 parent: 70990:a7099a3b5e5f parent: 70994:f852e2d556af user: Ezio Melotti date: Sun Jun 26 13:39:35 2011 +0300 summary: #11363: merge with 3.2. files: Doc/library/curses.rst | 222 +++++++++++++++++----------- 1 files changed, 135 insertions(+), 87 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -72,7 +72,7 @@ .. function:: baudrate() - Returns the output speed of the terminal in bits per second. On software + Return the output speed of the terminal in bits per second. On software terminal emulators it will have a fixed high value. Included for historical reasons; in former times, it was used to write output loops for time delays and occasionally to change interfaces depending on the line speed. @@ -85,7 +85,7 @@ .. function:: can_change_color() - Returns true or false, depending on whether the programmer can change the colors + Return ``True`` or ``False``, depending on whether the programmer can change the colors displayed by the terminal. @@ -100,7 +100,7 @@ .. function:: color_content(color_number) - Returns the intensity of the red, green, and blue (RGB) components in the color + Return the intensity of the red, green, and blue (RGB) components in the color *color_number*, which must be between ``0`` and :const:`COLORS`. A 3-tuple is returned, containing the R,G,B values for the given color, which will be between ``0`` (no component) and ``1000`` (maximum amount of component). @@ -108,7 +108,7 @@ .. function:: color_pair(color_number) - Returns the attribute value for displaying text in the specified color. This + Return the attribute value for displaying text in the specified color. This attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`, and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart to this function. @@ -116,7 +116,7 @@ .. function:: curs_set(visibility) - Sets the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, + Set the cursor state. *visibility* can be set to 0, 1, or 2, for invisible, normal, or very visible. If the terminal supports the visibility requested, the previous cursor state is returned; otherwise, an exception is raised. On many terminals, the "visible" mode is an underline cursor and the "very visible" mode @@ -125,7 +125,7 @@ .. function:: def_prog_mode() - Saves the current terminal mode as the "program" mode, the mode when the running + Save the current terminal mode as the "program" mode, the mode when the running program is using curses. (Its counterpart is the "shell" mode, for when the program is not in curses.) Subsequent calls to :func:`reset_prog_mode` will restore this mode. @@ -133,7 +133,7 @@ .. function:: def_shell_mode() - Saves the current terminal mode as the "shell" mode, the mode when the running + Save the current terminal mode as the "shell" mode, the mode when the running program is not using curses. (Its counterpart is the "program" mode, when the program is using curses capabilities.) Subsequent calls to :func:`reset_shell_mode` will restore this mode. @@ -141,7 +141,7 @@ .. function:: delay_output(ms) - Inserts an *ms* millisecond pause in output. + Insert an *ms* millisecond pause in output. .. function:: doupdate() @@ -172,7 +172,7 @@ .. function:: erasechar() - Returns the user's current erase character. Under Unix operating systems this + Return the user's current erase character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. @@ -180,7 +180,7 @@ .. function:: filter() The :func:`.filter` routine, if used, must be called before :func:`initscr` is - called. The effect is that, during those calls, LINES is set to 1; the + called. The effect is that, during those calls, :envvar:`LINES` is set to 1; the capabilities clear, cup, cud, cud1, cuu1, cuu, vpa are disabled; and the home string is set to the value of cr. The effect is that the cursor is confined to the current line, and so are screen updates. This may be used for enabling @@ -206,7 +206,7 @@ method should be call to retrieve the queued mouse event, represented as a 5-tuple ``(id, x, y, z, bstate)``. *id* is an ID value used to distinguish multiple devices, and *x*, *y*, *z* are the event's coordinates. (*z* is - currently unused.). *bstate* is an integer value whose bits will be set to + currently unused.) *bstate* is an integer value whose bits will be set to indicate the type of event, and will be the bitwise OR of one or more of the following constants, where *n* is the button number from 1 to 4: :const:`BUTTONn_PRESSED`, :const:`BUTTONn_RELEASED`, :const:`BUTTONn_CLICKED`, @@ -216,32 +216,32 @@ .. function:: getsyx() - Returns the current coordinates of the virtual screen cursor in y and x. If + Return the current coordinates of the virtual screen cursor in y and x. If leaveok is currently true, then -1,-1 is returned. .. function:: getwin(file) - Reads window related data stored in the file by an earlier :func:`putwin` call. + Read window related data stored in the file by an earlier :func:`putwin` call. The routine then creates and initializes a new window using that data, returning the new window object. .. function:: has_colors() - Returns true if the terminal can display colors; otherwise, it returns false. + Return ``True`` if the terminal can display colors; otherwise, return ``False``. .. function:: has_ic() - Returns true if the terminal has insert- and delete- character capabilities. + Return ``True`` if the terminal has insert- and delete-character capabilities. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. .. function:: has_il() - Returns true if the terminal has insert- and delete-line capabilities, or can + Return ``True`` if the terminal has insert- and delete-line capabilities, or can simulate them using scrolling regions. This function is included for historical reasons only, as all modern software terminal emulators have such capabilities. @@ -249,7 +249,7 @@ .. function:: has_key(ch) - Takes a key value *ch*, and returns true if the current terminal type recognizes + Take a key value *ch*, and return ``True`` if the current terminal type recognizes a key with that value. @@ -258,13 +258,13 @@ Used for half-delay mode, which is similar to cbreak mode in that characters typed by the user are immediately available to the program. However, after blocking for *tenths* tenths of seconds, an exception is raised if nothing has - been typed. The value of *tenths* must be a number between 1 and 255. Use + been typed. The value of *tenths* must be a number between ``1`` and ``255``. Use :func:`nocbreak` to leave half-delay mode. .. function:: init_color(color_number, r, g, b) - Changes the definition of a color, taking the number of the color to be changed + Change the definition of a color, taking the number of the color to be changed followed by three RGB values (for the amounts of red, green, and blue components). The value of *color_number* must be between ``0`` and :const:`COLORS`. Each of *r*, *g*, *b*, must be a value between ``0`` and @@ -275,7 +275,7 @@ .. function:: init_pair(pair_number, fg, bg) - Changes the definition of a color-pair. It takes three arguments: the number of + Change the definition of a color-pair. It takes three arguments: the number of the color-pair to be changed, the foreground color number, and the background color number. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1`` (the ``0`` color pair is wired to white on black and cannot @@ -287,7 +287,7 @@ .. function:: initscr() - Initialize the library. Returns a :class:`WindowObject` which represents the + Initialize the library. Return a :class:`WindowObject` which represents the whole screen. .. note:: @@ -296,9 +296,15 @@ cause the interpreter to exit. +.. function:: is_term_resized(nlines, ncols) + + Return ``True`` if :func:`resize_term` would modify the window structure, + ``False`` otherwise. + + .. function:: isendwin() - Returns true if :func:`endwin` has been called (that is, the curses library has + Return ``True`` if :func:`endwin` has been called (that is, the curses library has been deinitialized). @@ -314,14 +320,14 @@ .. function:: killchar() - Returns the user's current line kill character. Under Unix operating systems + Return the user's current line kill character. Under Unix operating systems this is a property of the controlling tty of the curses program, and is not set by the curses library itself. .. function:: longname() - Returns a string containing the terminfo long name field describing the current + Return a string containing the terminfo long name field describing the current terminal. The maximum length of a verbose description is 128 characters. It is defined only after the call to :func:`initscr`. @@ -334,14 +340,14 @@ .. function:: mouseinterval(interval) - Sets the maximum time in milliseconds that can elapse between press and release - events in order for them to be recognized as a click, and returns the previous + Set the maximum time in milliseconds that can elapse between press and release + events in order for them to be recognized as a click, and return the previous interval value. The default value is 200 msec, or one fifth of a second. .. function:: mousemask(mousemask) - Sets the mouse events to be reported, and returns a tuple ``(availmask, + Set the mouse events to be reported, and return a tuple ``(availmask, oldmask)``. *availmask* indicates which of the specified mouse events can be reported; on complete failure it returns 0. *oldmask* is the previous value of the given window's mouse event mask. If this function is never called, no mouse @@ -355,7 +361,7 @@ .. function:: newpad(nlines, ncols) - Creates and returns a pointer to a new pad data structure with the given number + Create and return a pointer to a new pad data structure with the given number of lines and columns. A pad is returned as a window object. A pad is like a window, except that it is not restricted by the screen size, and @@ -365,9 +371,9 @@ echoing of input) do not occur. The :meth:`refresh` and :meth:`noutrefresh` methods of a pad require 6 arguments to specify the part of the pad to be displayed and the location on the screen to be used for the display. The - arguments are pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol; the p + arguments are *pminrow*, *pmincol*, *sminrow*, *smincol*, *smaxrow*, *smaxcol*; the *p* arguments refer to the upper left corner of the pad region to be displayed and - the s arguments define a clipping box on the screen within which the pad region + the *s* arguments define a clipping box on the screen within which the pad region is to be displayed. @@ -409,7 +415,7 @@ .. function:: noqiflush() - When the noqiflush routine is used, normal flush of input and output queues + When the :func:`noqiflush` routine is used, normal flush of input and output queues associated with the INTR, QUIT and SUSP characters will not be done. You may want to call :func:`noqiflush` in a signal handler if you want output to continue as though the interrupt had not occurred, after the handler exits. @@ -422,27 +428,27 @@ .. function:: pair_content(pair_number) - Returns a tuple ``(fg, bg)`` containing the colors for the requested color pair. + Return a tuple ``(fg, bg)`` containing the colors for the requested color pair. The value of *pair_number* must be between ``1`` and ``COLOR_PAIRS - 1``. .. function:: pair_number(attr) - Returns the number of the color-pair set by the attribute value *attr*. + Return the number of the color-pair set by the attribute value *attr*. :func:`color_pair` is the counterpart to this function. .. function:: putp(string) - Equivalent to ``tputs(str, 1, putchar)``; emits the value of a specified - terminfo capability for the current terminal. Note that the output of putp + Equivalent to ``tputs(str, 1, putchar)``; emit the value of a specified + terminfo capability for the current terminal. Note that the output of :func:`putp` always goes to standard output. .. function:: qiflush( [flag] ) - If *flag* is false, the effect is the same as calling :func:`noqiflush`. If - *flag* is true, or no argument is provided, the queues will be flushed when + If *flag* is ``False``, the effect is the same as calling :func:`noqiflush`. If + *flag* is ``True``, or no argument is provided, the queues will be flushed when these control characters are read. @@ -455,26 +461,55 @@ .. function:: reset_prog_mode() - Restores the terminal to "program" mode, as previously saved by + Restore the terminal to "program" mode, as previously saved by :func:`def_prog_mode`. .. function:: reset_shell_mode() - Restores the terminal to "shell" mode, as previously saved by + Restore the terminal to "shell" mode, as previously saved by :func:`def_shell_mode`. +.. function:: resetty() + + Restore the state of the terminal modes to what it was at the last call to + :func:`savetty`. + + +.. function:: resize_term(nlines, ncols) + + Backend function used by :func:`resizeterm`, performing most of the work; + when resizing the windows, :func:`resize_term` blank-fills the areas that are + extended. The calling application should fill in these areas with + appropriate data. The :func:`resize_term` function attempts to resize all + windows. However, due to the calling convention of pads, it is not possible + to resize these without additional interaction with the application. + + +.. function:: resizeterm(nlines, ncols) + + Resize the standard and current windows to the specified dimensions, and + adjusts other bookkeeping data used by the curses library that record the + window dimensions (in particular the SIGWINCH handler). + + +.. function:: savetty() + + Save the current state of the terminal modes in a buffer, usable by + :func:`resetty`. + + .. function:: setsyx(y, x) - Sets the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then + Set the virtual screen cursor to *y*, *x*. If *y* and *x* are both -1, then leaveok is set. .. function:: setupterm([termstr, fd]) - Initializes the terminal. *termstr* is a string giving the terminal name; if - omitted, the value of the TERM environment variable will be used. *fd* is the + Initialize the terminal. *termstr* is a string giving the terminal name; if + omitted, the value of the :envvar:`TERM` environment variable will be used. *fd* is the file descriptor to which any initialization sequences will be sent; if not supplied, the file descriptor for ``sys.stdout`` will be used. @@ -494,19 +529,19 @@ .. function:: termattrs() - Returns a logical OR of all video attributes supported by the terminal. This + Return a logical OR of all video attributes supported by the terminal. This information is useful when a curses program needs complete control over the appearance of the screen. .. function:: termname() - Returns the value of the environment variable TERM, truncated to 14 characters. + Return the value of the environment variable :envvar:`TERM`, truncated to 14 characters. .. function:: tigetflag(capname) - Returns the value of the Boolean capability corresponding to the terminfo + Return the value of the Boolean capability corresponding to the terminfo capability name *capname*. The value ``-1`` is returned if *capname* is not a Boolean capability, or ``0`` if it is canceled or absent from the terminal description. @@ -514,7 +549,7 @@ .. function:: tigetnum(capname) - Returns the value of the numeric capability corresponding to the terminfo + Return the value of the numeric capability corresponding to the terminfo capability name *capname*. The value ``-2`` is returned if *capname* is not a numeric capability, or ``-1`` if it is canceled or absent from the terminal description. @@ -522,22 +557,22 @@ .. function:: tigetstr(capname) - Returns the value of the string capability corresponding to the terminfo + Return the value of the string capability corresponding to the terminfo capability name *capname*. ``None`` is returned if *capname* is not a string capability, or is canceled or absent from the terminal description. .. function:: tparm(str[, ...]) - Instantiates the string *str* with the supplied parameters, where *str* should - be a parameterized string obtained from the terminfo database. E.g. - ``tparm(tigetstr("cup"), 5, 3)`` could result in ``'\033[6;4H'``, the exact + Instantiate the string *str* with the supplied parameters, where *str* should + be a parameterized string obtained from the terminfo database. E.g. + ``tparm(tigetstr("cup"), 5, 3)`` could result in x``'\033[6;4H'``, the exact result depending on terminal type. .. function:: typeahead(fd) - Specifies that the file descriptor *fd* be used for typeahead checking. If *fd* + Specify that the file descriptor *fd* be used for typeahead checking. If *fd* is ``-1``, then no typeahead checking is done. The curses library does "line-breakout optimization" by looking for typeahead @@ -549,7 +584,7 @@ .. function:: unctrl(ch) - Returns a string which is a printable representation of the character *ch*. + Return a string which is a printable representation of the character *ch*. Control characters are displayed as a caret followed by the character, for example as ``^C``. Printing characters are left as they are. @@ -572,7 +607,7 @@ .. function:: use_env(flag) If used, this function should be called before :func:`initscr` or newterm are - called. When *flag* is false, the values of lines and columns specified in the + called. When *flag* is ``False``, the values of lines and columns specified in the terminfo database will be used, even if environment variables :envvar:`LINES` and :envvar:`COLUMNS` (used by default) are set, or if curses is running in a window (in which case default behavior would be to use the window size if @@ -656,7 +691,7 @@ .. method:: window.bkgd(ch[, attr]) - Sets the background property of the window to the character *ch*, with + Set the background property of the window to the character *ch*, with attributes *attr*. The change is then applied to every character position in that window: @@ -669,7 +704,7 @@ .. method:: window.bkgdset(ch[, attr]) - Sets the window's background. A window's background consists of a character and + Set the window's background. A window's background consists of a character and any combination of attributes. The attribute part of the background is combined (OR'ed) with all non-blank characters that are written into the window. Both the character and attribute parts of the background are combined with the blank @@ -714,12 +749,12 @@ .. method:: window.box([vertch, horch]) Similar to :meth:`border`, but both *ls* and *rs* are *vertch* and both *ts* and - bs are *horch*. The default corner characters are always used by this function. + *bs* are *horch*. The default corner characters are always used by this function. .. method:: window.chgat([y, x, ] [num,] attr) - Sets the attributes of *num* characters at the current cursor position, or at + Set the attributes of *num* characters at the current cursor position, or at position ``(y, x)`` if supplied. If no value of *num* is given or *num* = -1, the attribute will be set on all the characters to the end of the line. This function does not move the cursor. The changed line will be touched using the @@ -729,7 +764,7 @@ .. method:: window.clear() - Like :meth:`erase`, but also causes the whole window to be repainted upon next + Like :meth:`erase`, but also cause the whole window to be repainted upon next call to :meth:`refresh`. @@ -752,7 +787,7 @@ .. method:: window.cursyncup() - Updates the current cursor position of all the ancestors of the window to + Update the current cursor position of all the ancestors of the window to reflect the current cursor position of the window. @@ -763,14 +798,14 @@ .. method:: window.deleteln() - Delete the line under the cursor. All following lines are moved up by 1 line. + Delete the line under the cursor. All following lines are moved up by one line. .. method:: window.derwin([nlines, ncols,] begin_y, begin_x) An abbreviation for "derive window", :meth:`derwin` is the same as calling :meth:`subwin`, except that *begin_y* and *begin_x* are relative to the origin - of the window, rather than relative to the entire screen. Returns a window + of the window, rather than relative to the entire screen. Return a window object for the derived window. @@ -782,8 +817,8 @@ .. method:: window.enclose(y, x) - Tests whether the given pair of screen-relative character-cell coordinates are - enclosed by the given window, returning true or false. It is useful for + Test whether the given pair of screen-relative character-cell coordinates are + enclosed by the given window, returning ``True`` or ``False``. It is useful for determining what subset of the screen windows enclose the location of a mouse event. @@ -798,6 +833,11 @@ Return a tuple ``(y, x)`` of co-ordinates of upper-left corner. +.. method:: window.getbkgd() + + Return the given window's current background character/attribute pair. + + .. method:: window.getch([y, x]) Get a character. Note that the integer returned does *not* have to be in ASCII @@ -820,8 +860,8 @@ .. method:: window.getparyx() - Returns the beginning coordinates of this window relative to its parent window - into two integer variables y and x. Returns ``-1,-1`` if this window has no + Return the beginning coordinates of this window relative to its parent window + into two integer variables y and x. Return ``-1, -1`` if this window has no parent. @@ -844,8 +884,8 @@ .. method:: window.idcok(flag) - If *flag* is false, curses no longer considers using the hardware insert/delete - character feature of the terminal; if *flag* is true, use of character insertion + If *flag* is ``False``, curses no longer considers using the hardware insert/delete + character feature of the terminal; if *flag* is ``True``, use of character insertion and deletion is enabled. When curses is first initialized, use of character insert/delete is enabled by default. @@ -858,7 +898,7 @@ .. method:: window.immedok(flag) - If *flag* is true, any change in the window image automatically causes the + If *flag* is ``True``, any change in the window image automatically causes the window to be refreshed; you no longer have to call :meth:`refresh` yourself. However, it may degrade performance considerably, due to repeated calls to wrefresh. This option is disabled by default. @@ -878,7 +918,7 @@ .. method:: window.insdelln(nlines) - Inserts *nlines* lines into the specified window above the current line. The + Insert *nlines* lines into the specified window above the current line. The *nlines* bottom lines are lost. For negative *nlines*, delete *nlines* lines starting with the one under the cursor, and move the remaining lines up. The bottom *nlines* lines are cleared. The current cursor position remains the @@ -887,7 +927,7 @@ .. method:: window.insertln() - Insert a blank line under the cursor. All following lines are moved down by 1 + Insert a blank line under the cursor. All following lines are moved down by one line. @@ -910,23 +950,23 @@ .. method:: window.instr([y, x] [, n]) - Returns a string of characters, extracted from the window starting at the + Return a string of characters, extracted from the window starting at the current cursor position, or at *y*, *x* if specified. Attributes are stripped - from the characters. If *n* is specified, :meth:`instr` returns return a string + from the characters. If *n* is specified, :meth:`instr` returns a string at most *n* characters long (exclusive of the trailing NUL). .. method:: window.is_linetouched(line) - Returns true if the specified line was modified since the last call to - :meth:`refresh`; otherwise returns false. Raises a :exc:`curses.error` + Return ``True`` if the specified line was modified since the last call to + :meth:`refresh`; otherwise return ``False``. Raise a :exc:`curses.error` exception if *line* is not valid for the given window. .. method:: window.is_wintouched() - Returns true if the specified window was modified since the last call to - :meth:`refresh`; otherwise returns false. + Return ``True`` if the specified window was modified since the last call to + :meth:`refresh`; otherwise return ``False``. .. method:: window.keypad(yes) @@ -952,7 +992,7 @@ .. method:: window.mvderwin(y, x) - Moves the window inside its parent window. The screen-relative parameters of + Move the window inside its parent window. The screen-relative parameters of the window are not changed. This routine is used to display different parts of the parent window at the same physical position on the screen. @@ -1010,19 +1050,19 @@ .. method:: window.putwin(file) - Writes all data associated with the window into the provided file object. This + Write all data associated with the window into the provided file object. This information can be later retrieved using the :func:`getwin` function. .. method:: window.redrawln(beg, num) - Indicates that the *num* screen lines, starting at line *beg*, are corrupted and + Indicate that the *num* screen lines, starting at line *beg*, are corrupted and should be completely redrawn on the next :meth:`refresh` call. .. method:: window.redrawwin() - Touches the entire window, causing it to be completely redrawn on the next + Touch the entire window, causing it to be completely redrawn on the next :meth:`refresh` call. @@ -1043,6 +1083,14 @@ *sminrow*, or *smincol* are treated as if they were zero. +.. method:: window.resize(nlines, ncols) + + Reallocate storage for a curses window to adjust its dimensions to the + specified values. If either dimension is larger than the current values, the + window's data is filled with blanks that have the current background + rendition (as set by :meth:`bkgdset`) merged into them. + + .. method:: window.scroll([lines=1]) Scroll the screen or scrolling region upward by *lines* lines. @@ -1050,7 +1098,7 @@ .. method:: window.scrollok(flag) - Controls what happens when the cursor of a window is moved off the edge of the + Control what happens when the cursor of a window is moved off the edge of the window or scrolling region, either as a result of a newline action on the bottom line, or typing the last character of the last line. If *flag* is false, the cursor is left on the bottom line. If *flag* is true, the window is scrolled up @@ -1092,26 +1140,26 @@ .. method:: window.syncdown() - Touches each location in the window that has been touched in any of its ancestor + Touch each location in the window that has been touched in any of its ancestor windows. This routine is called by :meth:`refresh`, so it should almost never be necessary to call it manually. .. method:: window.syncok(flag) - If called with *flag* set to true, then :meth:`syncup` is called automatically + If called with *flag* set to ``True``, then :meth:`syncup` is called automatically whenever there is a change in the window. .. method:: window.syncup() - Touches all locations in ancestors of the window that have been changed in the + Touch all locations in ancestors of the window that have been changed in the window. .. method:: window.timeout(delay) - Sets blocking or non-blocking read behavior for the window. If *delay* is + Set blocking or non-blocking read behavior for the window. If *delay* is negative, blocking read is used (which will wait indefinitely for input). If *delay* is zero, then non-blocking read is used, and -1 will be returned by :meth:`getch` if no input is waiting. If *delay* is positive, then @@ -1134,7 +1182,7 @@ .. method:: window.untouchwin() - Marks all lines in the window as unchanged since the last call to + Mark all lines in the window as unchanged since the last call to :meth:`refresh`. @@ -1657,7 +1705,7 @@ .. method:: gather() - This method returns the window contents as a string; whether blanks in the + Return the window contents as a string; whether blanks in the window are included is affected by the :attr:`stripspaces` member. -- Repository URL: http://hg.python.org/cpython From barry at python.org Sun Jun 26 13:30:31 2011 From: barry at python.org (Barry Warsaw) Date: Sun, 26 Jun 2011 12:30:31 +0100 Subject: [Python-checkins] peps: Record Guido's acceptance of PEP 380 In-Reply-To: References: Message-ID: <20110626123031.5091420a@snowdog> On Jun 26, 2011, at 05:02 AM, nick.coghlan wrote: >http://hg.python.org/peps/rev/9f7a0b4e38a7 >changeset: 3889:9f7a0b4e38a7 >user: Nick Coghlan >date: Sun Jun 26 13:02:17 2011 +1000 >summary: > Record Guido's acceptance of PEP 380 > >files: > pep-0380.txt | 10 ++++++++-- > 1 files changed, 8 insertions(+), 2 deletions(-) > > >diff --git a/pep-0380.txt b/pep-0380.txt >--- a/pep-0380.txt >+++ b/pep-0380.txt >@@ -3,11 +3,11 @@ > Version: $Revision$ > Last-Modified: $Date$ > Author: Gregory Ewing >-Status: Draft >+Status: Accepted > Type: Standards Track > Content-Type: text/x-rst > Created: 13-Feb-2009 >-Python-Version: 3.x >+Python-Version: 3.3 > Post-History: Please add a Resolution header as per PEP 1. Thanks! -Barry -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: From python-checkins at python.org Sun Jun 26 14:30:40 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Jun 2011 14:30:40 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzQ2MDg6?= =?utf8?q?_urllib=2Erequest=2Eurlopen_does_not_return_an_iterable_object?= Message-ID: http://hg.python.org/cpython/rev/c0a68b948f5d changeset: 70996:c0a68b948f5d branch: 3.2 parent: 70994:f852e2d556af user: Raymond Hettinger date: Sun Jun 26 14:29:35 2011 +0200 summary: Issue #4608: urllib.request.urlopen does not return an iterable object files: Lib/test/test_urllib.py | 5 +++-- Lib/urllib/response.py | 12 ++++++++---- Misc/ACKS | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -110,8 +110,9 @@ # Test iterator # Don't need to count number of iterations since test would fail the # instant it returned anything beyond the first line from the - # comparison - for line in self.returned_obj.__iter__(): + # comparison. + # Use the iterator in the usual implicit way to test for ticket #4608. + for line in self.returned_obj: self.assertEqual(line, self.text) class ProxyTests(unittest.TestCase): diff --git a/Lib/urllib/response.py b/Lib/urllib/response.py --- a/Lib/urllib/response.py +++ b/Lib/urllib/response.py @@ -23,10 +23,14 @@ self.fileno = self.fp.fileno else: self.fileno = lambda: None - if hasattr(self.fp, "__iter__"): - self.__iter__ = self.fp.__iter__ - if hasattr(self.fp, "__next__"): - self.__next__ = self.fp.__next__ + + def __iter__(self): + # Assigning `__iter__` to the instance doesn't work as intended + # because the iter builtin does something like `cls.__iter__(obj)` + # and thus fails to find the _bound_ method `obj.__iter__`. + # Returning just `self.fp` works for built-in file objects but + # might not work for general file-like objects. + return iter(self.fp) def __repr__(self): return '<%s at %r whose fp = %r>' % (self.__class__.__name__, diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -309,6 +309,7 @@ Santiago Gala Yitzchak Gale Quentin Gallet-Gilles +Riccardo Attilio Galli Raymund Galvin Nitin Ganatra Fred Gansevles -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 14:30:41 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Jun 2011 14:30:41 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=234608=3A_urllib=2Erequest=2Eurlopen_does_not_return_?= =?utf8?q?an_iterable_object?= Message-ID: http://hg.python.org/cpython/rev/d4aeeddf72e3 changeset: 70997:d4aeeddf72e3 parent: 70995:b879bad40154 parent: 70996:c0a68b948f5d user: Raymond Hettinger date: Sun Jun 26 14:30:25 2011 +0200 summary: Issue #4608: urllib.request.urlopen does not return an iterable object files: Lib/test/test_urllib.py | 5 +++-- Lib/urllib/response.py | 12 ++++++++---- Misc/ACKS | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -110,8 +110,9 @@ # Test iterator # Don't need to count number of iterations since test would fail the # instant it returned anything beyond the first line from the - # comparison - for line in self.returned_obj.__iter__(): + # comparison. + # Use the iterator in the usual implicit way to test for ticket #4608. + for line in self.returned_obj: self.assertEqual(line, self.text) class ProxyTests(unittest.TestCase): diff --git a/Lib/urllib/response.py b/Lib/urllib/response.py --- a/Lib/urllib/response.py +++ b/Lib/urllib/response.py @@ -23,10 +23,14 @@ self.fileno = self.fp.fileno else: self.fileno = lambda: None - if hasattr(self.fp, "__iter__"): - self.__iter__ = self.fp.__iter__ - if hasattr(self.fp, "__next__"): - self.__next__ = self.fp.__next__ + + def __iter__(self): + # Assigning `__iter__` to the instance doesn't work as intended + # because the iter builtin does something like `cls.__iter__(obj)` + # and thus fails to find the _bound_ method `obj.__iter__`. + # Returning just `self.fp` works for built-in file objects but + # might not work for general file-like objects. + return iter(self.fp) def __repr__(self): return '<%s at %r whose fp = %r>' % (self.__class__.__name__, diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -325,6 +325,7 @@ Santiago Gala Yitzchak Gale Quentin Gallet-Gilles +Riccardo Attilio Galli Raymund Galvin Nitin Ganatra Fred Gansevles -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 15:29:42 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Jun 2011 15:29:42 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzg4OTA6?= =?utf8?q?_Remove_/tmp_from_examples=2E?= Message-ID: http://hg.python.org/cpython/rev/1ed71544fceb changeset: 70998:1ed71544fceb branch: 3.2 parent: 70996:c0a68b948f5d user: Raymond Hettinger date: Sun Jun 26 15:29:06 2011 +0200 summary: Issue #8890: Remove /tmp from examples. files: Doc/howto/logging-cookbook.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -723,7 +723,7 @@ # The size of the rotated files is made small so you can see the results easily. def listener_configurer(): root = logging.getLogger() - h = logging.handlers.RotatingFileHandler('/tmp/mptest.log', 'a', 300, 10) + h = logging.handlers.RotatingFileHandler('mptest.log', 'a', 300, 10) f = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s') h.setFormatter(f) root.addHandler(h) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Sun Jun 26 15:29:43 2011 From: python-checkins at python.org (raymond.hettinger) Date: Sun, 26 Jun 2011 15:29:43 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=238890=3A_Remove_/tmp_from_examples=2E?= Message-ID: http://hg.python.org/cpython/rev/fcf242243d46 changeset: 70999:fcf242243d46 parent: 70997:d4aeeddf72e3 parent: 70998:1ed71544fceb user: Raymond Hettinger date: Sun Jun 26 15:29:27 2011 +0200 summary: Issue #8890: Remove /tmp from examples. files: Doc/howto/logging-cookbook.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -723,7 +723,7 @@ # The size of the rotated files is made small so you can see the results easily. def listener_configurer(): root = logging.getLogger() - h = logging.handlers.RotatingFileHandler('/tmp/mptest.log', 'a', 300, 10) + h = logging.handlers.RotatingFileHandler('mptest.log', 'a', 300, 10) f = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s') h.setFormatter(f) root.addHandler(h) -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Sun Jun 26 15:55:02 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Sun, 26 Jun 2011 23:55:02 +1000 Subject: [Python-checkins] cpython (3.2): #11669: rephrase footnote in the Compound Statements page. In-Reply-To: References: Message-ID: On Sun, Jun 26, 2011 at 6:38 PM, ezio.melotti wrote: > -.. [#] The exception is propagated to the invocation stack only if there is no > - ? :keyword:`finally` clause that negates the exception. > +.. [#] The exception is propagated to the invocation stack unless > + ? there is a :keyword:`finally` clause which happens to raise another > + ? exception. That new exception causes the old one to be lost. I believe the footnote was talking about this case: >>> def f(): ... try: ... raise Exception() ... finally: ... return "What exception?" ... >>> f() 'What exception?' The new wording doesn't accurately reflect that. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Sun Jun 26 15:58:25 2011 From: python-checkins at python.org (nick.coghlan) Date: Sun, 26 Jun 2011 15:58:25 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Add_missing_Resolution_header?= Message-ID: http://hg.python.org/peps/rev/e44e79634a96 changeset: 3891:e44e79634a96 user: Nick Coghlan date: Sun Jun 26 23:58:03 2011 +1000 summary: Add missing Resolution header files: pep-0380.txt | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/pep-0380.txt b/pep-0380.txt --- a/pep-0380.txt +++ b/pep-0380.txt @@ -9,6 +9,7 @@ Created: 13-Feb-2009 Python-Version: 3.3 Post-History: +Resolution: http://mail.python.org/pipermail/python-dev/2011-June/112010.html Abstract -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Sun Jun 26 22:45:44 2011 From: python-checkins at python.org (senthil.kumaran) Date: Sun, 26 Jun 2011 22:45:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_closes_issu?= =?utf8?q?e1067702__The_problem_with_close_multiple_ftp_transfers_were_due?= Message-ID: http://hg.python.org/cpython/rev/a4d418e8010d changeset: 71000:a4d418e8010d branch: 2.7 parent: 70992:3dc602b1f4a2 user: Senthil Kumaran date: Sun Jun 26 13:45:17 2011 -0700 summary: Fix closes issue1067702 The problem with close multiple ftp transfers were due cases where sockets/file were not closed immediately. Tightned those cases and failure is no longer observed. files: Lib/ftplib.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -351,6 +351,7 @@ conn, sockaddr = sock.accept() if self.timeout is not _GLOBAL_DEFAULT_TIMEOUT: conn.settimeout(self.timeout) + sock.close() if resp[:3] == '150': # this is conditional in case we received a 125 size = parse150(resp) @@ -575,11 +576,11 @@ def close(self): '''Close the connection without assuming anything about it.''' - if self.file: + if self.file is not None: self.file.close() + if self.sock is not None: self.sock.close() - self.file = self.sock = None - + self.file = self.sock = None try: import ssl -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Mon Jun 27 05:08:16 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 27 Jun 2011 05:08:16 +0200 Subject: [Python-checkins] Daily reference leaks (fcf242243d46): sum=300 Message-ID: results for fcf242243d46 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogfA2T9z', '-x'] From python-checkins at python.org Mon Jun 27 08:50:01 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 27 Jun 2011 08:50:01 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_issu?= =?utf8?q?e_11568_-_update_select=2Eepoll=2Eregister_docstring_with_mentio?= =?utf8?q?n_of?= Message-ID: http://hg.python.org/cpython/rev/0610f70e6694 changeset: 71001:0610f70e6694 branch: 3.2 parent: 70998:1ed71544fceb user: Senthil Kumaran date: Sun Jun 26 23:48:23 2011 -0700 summary: Fix closes issue 11568 - update select.epoll.register docstring with mention of correct behavior. files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -916,7 +916,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 08:50:02 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 27 Jun 2011 08:50:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/ddb8a29a6bc5 changeset: 71002:ddb8a29a6bc5 parent: 70999:fcf242243d46 parent: 71001:0610f70e6694 user: Senthil Kumaran date: Sun Jun 26 23:49:49 2011 -0700 summary: merge from 3.2 files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -921,7 +921,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 08:51:23 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 27 Jun 2011 08:51:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fix_closes_issu?= =?utf8?q?e_11568_-_update_select=2Eepoll=2Eregister_docstring_with_mentio?= =?utf8?q?n_of?= Message-ID: http://hg.python.org/cpython/rev/a6586cb660dc changeset: 71003:a6586cb660dc branch: 2.7 parent: 71000:a4d418e8010d user: Senthil Kumaran date: Sun Jun 26 23:50:35 2011 -0700 summary: Fix closes issue 11568 - update select.epoll.register docstring with mention of correct behavior. files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -912,7 +912,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 11:17:57 2011 From: python-checkins at python.org (giampaolo.rodola) Date: Mon, 27 Jun 2011 11:17:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_12139=3A_add_CCC_comm?= =?utf8?q?and_support_to_FTP=5FTLS_class_to_revert_the_SSL?= Message-ID: http://hg.python.org/cpython/rev/d2eacbbdaf57 changeset: 71004:d2eacbbdaf57 parent: 71002:ddb8a29a6bc5 user: Giampaolo Rodola' date: Mon Jun 27 11:17:51 2011 +0200 summary: Issue 12139: add CCC command support to FTP_TLS class to revert the SSL connection back to clear-text. files: Doc/library/ftplib.rst | 8 ++++++++ Doc/whatsnew/3.3.rst | 11 +++++++++++ Lib/ftplib.py | 8 ++++++++ Lib/test/test_ftplib.py | 22 ++++++++++++++++++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -426,6 +426,14 @@ Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute. +.. method:: FTP_TLS.ccc() + + Revert control channel back to plaintex. This can be useful to take + advantage of firewalls that know how to handle NAT with non-secure FTP + without opening fixed ports. + + .. versionadded:: 3.3 + .. method:: FTP_TLS.prot_p() Set up secure data connection. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -192,6 +192,17 @@ * :func:`~ssl.RAND_pseudo_bytes`: generate pseudo-random bytes. +ftplib +------ + +The :class:`~ftplib.FTP_TLS` class now provides a new +:func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to +plaintex. This can be useful to take advantage of firewalls that know how to +handle NAT with non-secure FTP without opening fixed ports. + +(Patch submitted by Giampaolo Rodol? in :issue:`12139`.) + + Optimizations ============= diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -708,6 +708,14 @@ self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp + def ccc(self): + '''Switch back to a clear-text control connection.''' + if not isinstance(self.sock, ssl.SSLSocket): + raise ValueError("not using TLS") + resp = self.voidcmd('CCC') + self.sock = self.sock.unwrap() + return resp + def prot_p(self): '''Set up secure data connection.''' # PROT defines whether or not the data channel is to be protected. diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -303,11 +303,11 @@ _ssl_closing = False def secure_connection(self): - self.del_channel() socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False, certfile=CERTFILE, server_side=True, do_handshake_on_connect=False, ssl_version=ssl.PROTOCOL_SSLv23) + self.del_channel() self.set_socket(socket) self._ssl_accepting = True @@ -342,7 +342,10 @@ # http://www.mail-archive.com/openssl-users at openssl.org/msg60710.html pass self._ssl_closing = False - super(SSLConnection, self).close() + if getattr(self, '_ccc', False) == False: + super(SSLConnection, self).close() + else: + pass def handle_read_event(self): if self._ssl_accepting: @@ -410,12 +413,18 @@ def __init__(self, conn): DummyFTPHandler.__init__(self, conn) self.secure_data_channel = False + self._ccc = False def cmd_auth(self, line): """Set up secure control channel.""" self.push('234 AUTH TLS successful') self.secure_connection() + def cmd_ccc(self, line): + self.push('220 Reverting back to clear-text') + self._ccc = True + self._do_ssl_shutdown() + def cmd_pbsz(self, line): """Negotiate size of buffer for secure data transfer. For TLS/SSL the only valid value for the parameter is '0'. @@ -872,6 +881,15 @@ self.assertIs(sock.context, ctx) self.assertIsInstance(sock, ssl.SSLSocket) + def test_ccc(self): + self.assertRaises(ValueError, self.client.ccc) + self.client.login(secure=True) + self.assertIsInstance(self.client.sock, ssl.SSLSocket) + self.client.ccc() + self.assertRaises(ValueError, self.client.sock.unwrap) + self.client.sendcmd('noop') + self.client.quit() + class TestTimeouts(TestCase): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:10 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:10 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_update_profile_?= =?utf8?q?license_=28closes_=2312417=29?= Message-ID: http://hg.python.org/cpython/rev/55219254eb77 changeset: 71005:55219254eb77 branch: 2.7 parent: 71000:a4d418e8010d user: Benjamin Peterson date: Mon Jun 27 09:14:34 2011 -0500 summary: update profile license (closes #12417) files: Lib/profile.py | 39 +++++++++++++--------------------- Lib/pstats.py | 42 +++++++++++++++---------------------- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -2,35 +2,26 @@ # # Class for profiling python code. rev 1.0 6/2/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum """Class for profiling Python code.""" -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -2,34 +2,26 @@ # Class for printing reports on profiled python code. rev 1.0 4/1/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum -# -# see profile.py for more info. -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +"""Class for profiling Python code.""" + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:11 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:11 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_update_profile_?= =?utf8?q?license_=28closes_=2312417=29?= Message-ID: http://hg.python.org/cpython/rev/e50963c3119d changeset: 71006:e50963c3119d branch: 3.2 parent: 70998:1ed71544fceb user: Benjamin Peterson date: Mon Jun 27 09:14:34 2011 -0500 summary: update profile license (closes #12417) files: Lib/profile.py | 39 +++++++++++++--------------------- Lib/pstats.py | 42 +++++++++++++++---------------------- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -2,35 +2,26 @@ # # Class for profiling python code. rev 1.0 6/2/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum """Class for profiling Python code.""" -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -2,34 +2,26 @@ # Class for printing reports on profiled python code. rev 1.0 4/1/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum -# -# see profile.py for more info. -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +"""Class for profiling Python code.""" + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:12 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:12 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiBtZXJnZSAzLjIgKCMxMjQxNyk=?= Message-ID: http://hg.python.org/cpython/rev/5ae1711d9c19 changeset: 71007:5ae1711d9c19 parent: 70999:fcf242243d46 parent: 71006:e50963c3119d user: Benjamin Peterson date: Mon Jun 27 09:15:19 2011 -0500 summary: merge 3.2 (#12417) files: Lib/profile.py | 39 +++++++++++++--------------------- Lib/pstats.py | 42 +++++++++++++++---------------------- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -2,35 +2,26 @@ # # Class for profiling python code. rev 1.0 6/2/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum """Class for profiling Python code.""" -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -2,34 +2,26 @@ # Class for printing reports on profiled python code. rev 1.0 4/1/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum -# -# see profile.py for more info. -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +"""Class for profiling Python code.""" + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:13 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:13 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/7b381d8f89d1 changeset: 71008:7b381d8f89d1 branch: 2.7 parent: 71005:55219254eb77 parent: 71003:a6586cb660dc user: Benjamin Peterson date: Mon Jun 27 09:16:23 2011 -0500 summary: merge heads files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -912,7 +912,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:13 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:13 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/aa5b09802c26 changeset: 71009:aa5b09802c26 parent: 71007:5ae1711d9c19 parent: 71001:0610f70e6694 user: Benjamin Peterson date: Mon Jun 27 09:16:40 2011 -0500 summary: merge 3.2 files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -921,7 +921,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:14 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:14 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/f444313a81be changeset: 71010:f444313a81be parent: 71009:aa5b09802c26 parent: 71004:d2eacbbdaf57 user: Benjamin Peterson date: Mon Jun 27 09:16:47 2011 -0500 summary: merge heads files: Doc/library/ftplib.rst | 8 ++++++++ Doc/whatsnew/3.3.rst | 11 +++++++++++ Lib/ftplib.py | 8 ++++++++ Lib/test/test_ftplib.py | 22 ++++++++++++++++++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -426,6 +426,14 @@ Set up secure control connection by using TLS or SSL, depending on what specified in :meth:`ssl_version` attribute. +.. method:: FTP_TLS.ccc() + + Revert control channel back to plaintex. This can be useful to take + advantage of firewalls that know how to handle NAT with non-secure FTP + without opening fixed ports. + + .. versionadded:: 3.3 + .. method:: FTP_TLS.prot_p() Set up secure data connection. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -192,6 +192,17 @@ * :func:`~ssl.RAND_pseudo_bytes`: generate pseudo-random bytes. +ftplib +------ + +The :class:`~ftplib.FTP_TLS` class now provides a new +:func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to +plaintex. This can be useful to take advantage of firewalls that know how to +handle NAT with non-secure FTP without opening fixed ports. + +(Patch submitted by Giampaolo Rodol? in :issue:`12139`.) + + Optimizations ============= diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -708,6 +708,14 @@ self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp + def ccc(self): + '''Switch back to a clear-text control connection.''' + if not isinstance(self.sock, ssl.SSLSocket): + raise ValueError("not using TLS") + resp = self.voidcmd('CCC') + self.sock = self.sock.unwrap() + return resp + def prot_p(self): '''Set up secure data connection.''' # PROT defines whether or not the data channel is to be protected. diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -303,11 +303,11 @@ _ssl_closing = False def secure_connection(self): - self.del_channel() socket = ssl.wrap_socket(self.socket, suppress_ragged_eofs=False, certfile=CERTFILE, server_side=True, do_handshake_on_connect=False, ssl_version=ssl.PROTOCOL_SSLv23) + self.del_channel() self.set_socket(socket) self._ssl_accepting = True @@ -342,7 +342,10 @@ # http://www.mail-archive.com/openssl-users at openssl.org/msg60710.html pass self._ssl_closing = False - super(SSLConnection, self).close() + if getattr(self, '_ccc', False) == False: + super(SSLConnection, self).close() + else: + pass def handle_read_event(self): if self._ssl_accepting: @@ -410,12 +413,18 @@ def __init__(self, conn): DummyFTPHandler.__init__(self, conn) self.secure_data_channel = False + self._ccc = False def cmd_auth(self, line): """Set up secure control channel.""" self.push('234 AUTH TLS successful') self.secure_connection() + def cmd_ccc(self, line): + self.push('220 Reverting back to clear-text') + self._ccc = True + self._do_ssl_shutdown() + def cmd_pbsz(self, line): """Negotiate size of buffer for secure data transfer. For TLS/SSL the only valid value for the parameter is '0'. @@ -872,6 +881,15 @@ self.assertIs(sock.context, ctx) self.assertIsInstance(sock, ssl.SSLSocket) + def test_ccc(self): + self.assertRaises(ValueError, self.client.ccc) + self.client.login(secure=True) + self.assertIsInstance(self.client.sock, ssl.SSLSocket) + self.client.ccc() + self.assertRaises(ValueError, self.client.sock.unwrap) + self.client.sendcmd('noop') + self.client.quit() + class TestTimeouts(TestCase): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:15 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:15 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/ea1c38662a75 changeset: 71011:ea1c38662a75 branch: 3.2 parent: 71006:e50963c3119d parent: 71001:0610f70e6694 user: Benjamin Peterson date: Mon Jun 27 09:16:14 2011 -0500 summary: merge heads files: Modules/selectmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -916,7 +916,7 @@ PyDoc_STRVAR(pyepoll_register_doc, "register(fd[, eventmask]) -> None\n\ \n\ -Registers a new fd or modifies an already registered fd.\n\ +Registers a new fd or raises an IOError if the fd is already registered.\n\ fd is the target file descriptor of the operation.\n\ events is a bit set composed of the various EPOLL constants; the default\n\ is EPOLL_IN | EPOLL_OUT | EPOLL_PRI.\n\ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:15 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:15 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_strip_trailing_?= =?utf8?q?ws?= Message-ID: http://hg.python.org/cpython/rev/5d08c2a6274d changeset: 71012:5d08c2a6274d branch: 2.7 parent: 71008:7b381d8f89d1 user: Benjamin Peterson date: Mon Jun 27 09:18:46 2011 -0500 summary: strip trailing ws files: Lib/profile.py | 6 +++--- Lib/pstats.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:16 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:16 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_strip_trailing_?= =?utf8?q?ws?= Message-ID: http://hg.python.org/cpython/rev/adc244036ef7 changeset: 71013:adc244036ef7 branch: 3.2 parent: 71011:ea1c38662a75 user: Benjamin Peterson date: Mon Jun 27 09:18:46 2011 -0500 summary: strip trailing ws files: Lib/profile.py | 6 +++--- Lib/pstats.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:19:17 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 16:19:17 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/328fb2bbcd56 changeset: 71014:328fb2bbcd56 parent: 71010:f444313a81be parent: 71013:adc244036ef7 user: Benjamin Peterson date: Mon Jun 27 09:19:02 2011 -0500 summary: merge 3.2 files: Lib/profile.py | 6 +++--- Lib/pstats.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 16:24:18 2011 From: python-checkins at python.org (nick.coghlan) Date: Mon, 27 Jun 2011 16:24:18 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Happy_Tau_Day_folks!_=3A=29?= Message-ID: http://hg.python.org/peps/rev/1e3d663c67ee changeset: 3892:1e3d663c67ee user: Nick Coghlan date: Tue Jun 28 00:23:57 2011 +1000 summary: Happy Tau Day folks! :) files: pep-0628.html | 149 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 149 insertions(+), 0 deletions(-) diff --git a/pep-0628.html b/pep-0628.html new file mode 100644 --- /dev/null +++ b/pep-0628.html @@ -0,0 +1,149 @@ + + +++ + + + + + + + + + + + + + + + + + + + + + + + + + +
PEP:628
Title:Add math.tau
Version:$Revision$
Last-Modified:$Date$
Author:Nick Coghlan <ncoghlan at gmail.com>
Status:Deferred
Type:Standards Track
Content-Type:text/x-rst
Created:2011-06-28
Python-Version:3.3
Post-History:2011-06-28
Resolution:TBD
+


+ +
+

Abstract

+

In honour of Tau Day 2011, this PEP proposes the addition of the circle +constant math.tau to the Python standard library.

+

The concept of tau (?) is based on the observation that the ratio of a +circle's circumference to its radius is far more fundamental and interesting +than the ratio between its circumference and diameter. It is simply a matter +of assigning a name to the value 2 * pi (2?).

+
+
+

PEP Deferral

+

The idea in this PEP was first proposed in the auspiciously named +issue 12345 [1]. The immediate negative reactions I received from other core +developers on that issue made it clear to me that there wasn't likely to be +much collective interest in being part of a movement towards greater clarity +in the explanation of profound mathematical concepts that are unnecessarily +obscured by a historical quirk of notation.

+

Accordingly, this PEP is being submitted in a Deferred state, in the hope +that it may someday be revisited if the mathematical and educational +establishment choose to adopt a more enlightened and informative notation +for dealing with radians.

+

Converts to the merits of tau as the more fundamental circle constant +should feel free to start their mathematical code with tau = 2 * math.pi.

+
+
+

The Rationale for Tau

+

pi is defined as the ratio of a circle's circumference to its diameter. +However, a circle is defined by its centre point and its radius. This is +shown clearly when we note that the parameter of integration to go from a +circle's circumference to its area is the radius, not the diameter. If we +use the diameter instead we have to divide by four to get rid of the +extraneous multiplier.

+

When working with radians, it is trivial to convert any given fraction of a +circle to a value in radians in terms of tau. A quarter circle is +tau/4, a half circle is tau/2, seven 25ths is 7*tau/25, etc. In +contrast with the equivalent expressions in terms of pi (pi/2, pi, +14*pi/25), the unnecessary and needlessly confusing multiplication by +two is gone.

+
+
+

Other Resources

+

I've barely skimmed the surface of the many examples put forward to point out +just how much easier and more sensible many aspects of mathematics become +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:

+
+ +
+
+ + + -- Repository URL: http://hg.python.org/peps From benjamin at python.org Mon Jun 27 16:38:10 2011 From: benjamin at python.org (Benjamin Peterson) Date: Mon, 27 Jun 2011 09:38:10 -0500 Subject: [Python-checkins] peps: Happy Tau Day folks! :) In-Reply-To: References: Message-ID: 2011/6/27 nick.coghlan : > http://hg.python.org/peps/rev/1e3d663c67ee > changeset: ? 3892:1e3d663c67ee > user: ? ? ? ?Nick Coghlan > date: ? ? ? ?Tue Jun 28 00:23:57 2011 +1000 > summary: > ?Happy Tau Day folks! :) > > files: > ?pep-0628.html | ?149 ++++++++++++++++++++++++++++++++++++++ You're not going to give us the source? -- Regards, Benjamin From python-checkins at python.org Mon Jun 27 16:40:10 2011 From: python-checkins at python.org (nick.coghlan) Date: Mon, 27 Jun 2011 16:40:10 +0200 Subject: [Python-checkins] =?utf8?q?peps=3A_Take_two=2C_this_time_with_the?= =?utf8?q?_correct_extension_=3A=29?= Message-ID: http://hg.python.org/peps/rev/4bbdebc71ad9 changeset: 3893:4bbdebc71ad9 user: Nick Coghlan date: Tue Jun 28 00:40:02 2011 +1000 summary: Take two, this time with the correct extension :) files: pep-0628.html | 148 -------------------------------------- pep-0628.txt | 100 +++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 148 deletions(-) diff --git a/pep-0628.html b/pep-0628.html deleted file mode 100644 --- a/pep-0628.html +++ /dev/null @@ -1,149 +0,0 @@ - - --- - - - - - - - - - - - - - - - - - - - - - - - - - -
PEP:628
Title:Add math.tau
Version:$Revision$
Last-Modified:$Date$
Author:Nick Coghlan <ncoghlan at gmail.com>
Status:Deferred
Type:Standards Track
Content-Type:text/x-rst
Created:2011-06-28
Python-Version:3.3
Post-History:2011-06-28
Resolution:TBD
-
- -
-

Abstract

-

In honour of Tau Day 2011, this PEP proposes the addition of the circle -constant math.tau to the Python standard library.

-

The concept of tau (?) is based on the observation that the ratio of a -circle's circumference to its radius is far more fundamental and interesting -than the ratio between its circumference and diameter. It is simply a matter -of assigning a name to the value 2 * pi (2?).

-
-
-

PEP Deferral

-

The idea in this PEP was first proposed in the auspiciously named -issue 12345 [1]. The immediate negative reactions I received from other core -developers on that issue made it clear to me that there wasn't likely to be -much collective interest in being part of a movement towards greater clarity -in the explanation of profound mathematical concepts that are unnecessarily -obscured by a historical quirk of notation.

-

Accordingly, this PEP is being submitted in a Deferred state, in the hope -that it may someday be revisited if the mathematical and educational -establishment choose to adopt a more enlightened and informative notation -for dealing with radians.

-

Converts to the merits of tau as the more fundamental circle constant -should feel free to start their mathematical code with tau = 2 * math.pi.

-
-
-

The Rationale for Tau

-

pi is defined as the ratio of a circle's circumference to its diameter. -However, a circle is defined by its centre point and its radius. This is -shown clearly when we note that the parameter of integration to go from a -circle's circumference to its area is the radius, not the diameter. If we -use the diameter instead we have to divide by four to get rid of the -extraneous multiplier.

-

When working with radians, it is trivial to convert any given fraction of a -circle to a value in radians in terms of tau. A quarter circle is -tau/4, a half circle is tau/2, seven 25ths is 7*tau/25, etc. In -contrast with the equivalent expressions in terms of pi (pi/2, pi, -14*pi/25), the unnecessary and needlessly confusing multiplication by -two is gone.

-
-
-

Other Resources

-

I've barely skimmed the surface of the many examples put forward to point out -just how much easier and more sensible many aspects of mathematics become -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:

-
- -
-
- - - diff --git a/pep-0628.txt b/pep-0628.txt new file mode 100644 --- /dev/null +++ b/pep-0628.txt @@ -0,0 +1,100 @@ +PEP: 628 +Title: Add ``math.tau`` +Version: $Revision$ +Last-Modified: $Date$ +Author: Nick Coghlan +Status: Deferred +Type: Standards Track +Content-Type: text/x-rst +Created: 2011-06-28 +Python-Version: 3.x +Post-History: 2011-06-28 +Resolution: TBD + + +Abstract +======== + +In honour of Tau Day 2011, this PEP proposes the addition of the circle +constant ``math.tau`` to the Python standard library. + +The concept of ``tau`` (``?``) is based on the observation that the ratio of a +circle's circumference to its radius is far more fundamental and interesting +than the ratio between its circumference and diameter. It is simply a matter +of assigning a name to the value ``2 * pi`` (``2?``). + + +PEP Deferral +============ + +The idea in this PEP was first proposed in the auspiciously named +`issue 12345`_. The immediate negative reactions I received from other core +developers on that issue made it clear to me that there wasn't likely to be +much collective interest in being part of a movement towards greater clarity +in the explanation of profound mathematical concepts that are unnecessarily +obscured by a historical quirk of notation. + +Accordingly, this PEP is being submitted in a Deferred state, in the hope +that it may someday be revisited if the mathematical and educational +establishment choose to adopt a more enlightened and informative notation +for dealing with radians. + +Converts to the merits of ``tau`` as the more fundamental circle constant +should feel free to start their mathematical code with ``tau = 2 * math.pi``. + +.. _issue 12345: http://bugs.python.org/issue12345 + + +The Rationale for Tau +===================== + +``pi`` is defined as the ratio of a circle's circumference to its diameter. +However, a circle is defined by its centre point and its *radius*. This is +shown clearly when we note that the parameter of integration to go from a +circle's circumference to its area is the radius, not the diameter. If we +use the diameter instead we have to divide by four to get rid of the +extraneous multiplier. + +When working with radians, it is trivial to convert any given fraction of a +circle to a value in radians in terms of ``tau``. A quarter circle is +``tau/4``, a half circle is ``tau/2``, seven 25ths is ``7*tau/25``, etc. In +contrast with the equivalent expressions in terms of ``pi`` (``pi/2``, ``pi``, +``14*pi/25``), the unnecessary and needlessly confusing multiplication by +two is gone. + + +Other Resources +=============== + +I've barely skimmed the surface of the many examples put forward to point out +just how much *easier* and more *sensible* many aspects of mathematics become +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 + +.. _Tau Manifesto: http://tauday.com/ +.. _Pi is (still) wrong: http://www.youtube.com/watch?v=jG7vhMMXagQ +.. _Pi is wrong!: http://www.youtube.com/watch?v=IF1zcRoOVN0 +.. _a page of resources: http://www.math.utah.edu/~palais/pi.html + + +Copyright +========= + +This document has been placed in the public domain. + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: -- Repository URL: http://hg.python.org/peps From python-checkins at python.org Mon Jun 27 16:40:47 2011 From: python-checkins at python.org (vinay.sajip) Date: Mon, 27 Jun 2011 16:40:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Closes_=2312419=3A_Added_id?= =?utf8?q?ent_to_SysLogHandler=2E?= Message-ID: http://hg.python.org/cpython/rev/6baa90fa2b6d changeset: 71015:6baa90fa2b6d user: Vinay Sajip date: Mon Jun 27 15:40:06 2011 +0100 summary: Closes #12419: Added ident to SysLogHandler. files: Doc/library/logging.handlers.rst | 9 +++++++++ Lib/logging/handlers.py | 3 +++ Lib/test/test_logging.py | 5 +++++ 3 files changed, 17 insertions(+), 0 deletions(-) diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -452,6 +452,15 @@ behaviour) but can be set to ``False`` on a ``SysLogHandler`` instance in order for that instance to *not* append the NUL terminator. + .. versionchanged:: 3.3 + (See: :issue:`12419`.) In earlier versions, there was no facility for + an "ident" or "tag" prefix to identify the source of the message. This + can now be specified using a class-level attribute, defaulting to + ``""`` to preserve existing behaviour, but which can be overridden on + a ``SysLogHandler`` instance in order for that instance to prepend + the ident to every message handled. Note that the provided ident must + be text, not bytes, and is prepended to the message exactly as is. + .. method:: encodePriority(facility, priority) Encodes the facility and priority into an integer. You can pass in strings diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -769,6 +769,7 @@ """ return self.priority_map.get(levelName, "warning") + ident = '' # prepended to all messages append_nul = True # some old syslog daemons expect a NUL terminator def emit(self, record): @@ -779,6 +780,8 @@ exception information is present, it is NOT sent to the server. """ msg = self.format(record) + if self.ident: + msg = self.ident + msg if self.append_nul: msg += '\000' """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1482,6 +1482,11 @@ logger.error("sp\xe4m") self.handled.wait() self.assertEqual(self.log_output, b'<11>\xef\xbb\xbfsp\xc3\xa4m') + self.handled.clear() + self.sl_hdlr.ident = "h\xe4m-" + logger.error("sp\xe4m") + self.handled.wait() + self.assertEqual(self.log_output, b'<11>\xef\xbb\xbfh\xc3\xa4m-sp\xc3\xa4m') @unittest.skipUnless(threading, 'Threading required for this test.') -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Mon Jun 27 16:45:08 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Tue, 28 Jun 2011 00:45:08 +1000 Subject: [Python-checkins] peps: Happy Tau Day folks! :) In-Reply-To: References: Message-ID: On Tue, Jun 28, 2011 at 12:38 AM, Benjamin Peterson wrote: > You're not going to give us the source? Just a teensy error with hg add, tab completion and not checking the diff before committing. Fixed now, though :) Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Mon Jun 27 18:07:25 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 27 Jun 2011 18:07:25 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_Fix_closes_Issu?= =?utf8?q?e12385_-_Clarify_maketrans_method_docstring_for_bytes_and?= Message-ID: http://hg.python.org/cpython/rev/586745894ab8 changeset: 71016:586745894ab8 branch: 3.2 parent: 71013:adc244036ef7 user: Senthil Kumaran date: Mon Jun 27 09:06:45 2011 -0700 summary: Fix closes Issue12385 - Clarify maketrans method docstring for bytes and bytearray object. files: Objects/bytes_methods.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -366,10 +366,10 @@ PyDoc_STRVAR_shared(_Py_maketrans__doc__, "B.maketrans(frm, to) -> translation table\n\ \n\ -Return a translation table (a bytes object of length 256)\n\ -suitable for use in bytes.translate where each byte in frm is\n\ -mapped to the byte at the same position in to.\n\ -The strings frm and to must be of the same length."); +Return a translation table (a bytes object of length 256) suitable\n\ +for use in the bytes or bytearray translate method where each byte\n\ +in frm is mapped to the byte at the same position in to.\n\ +The bytes objects frm and to must be of the same length."); static Py_ssize_t _getbuffer(PyObject *obj, Py_buffer *view) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 18:07:25 2011 From: python-checkins at python.org (senthil.kumaran) Date: Mon, 27 Jun 2011 18:07:25 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/66a14844e146 changeset: 71017:66a14844e146 parent: 71015:6baa90fa2b6d parent: 71016:586745894ab8 user: Senthil Kumaran date: Mon Jun 27 09:07:14 2011 -0700 summary: merge from 3.2 files: Objects/bytes_methods.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -366,10 +366,10 @@ PyDoc_STRVAR_shared(_Py_maketrans__doc__, "B.maketrans(frm, to) -> translation table\n\ \n\ -Return a translation table (a bytes object of length 256)\n\ -suitable for use in bytes.translate where each byte in frm is\n\ -mapped to the byte at the same position in to.\n\ -The strings frm and to must be of the same length."); +Return a translation table (a bytes object of length 256) suitable\n\ +for use in the bytes or bytearray translate method where each byte\n\ +in frm is mapped to the byte at the same position in to.\n\ +The bytes objects frm and to must be of the same length."); static Py_ssize_t _getbuffer(PyObject *obj, Py_buffer *view) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Mon Jun 27 23:22:57 2011 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 27 Jun 2011 23:22:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_don=27t_memoize_objects_tha?= =?utf8?q?t_are_their_own_copies_=28closes_=2312422=29?= Message-ID: http://hg.python.org/cpython/rev/e24ad85e9608 changeset: 71018:e24ad85e9608 user: Benjamin Peterson date: Mon Jun 27 16:22:46 2011 -0500 summary: don't memoize objects that are their own copies (closes #12422) Patch mostly by Alex Gaynor. files: Lib/copy.py | 12 +++++++----- Lib/test/test_copy.py | 19 +++++++++++++++++-- Misc/NEWS | 3 +++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py --- a/Lib/copy.py +++ b/Lib/copy.py @@ -173,8 +173,10 @@ "un(deep)copyable object of type %s" % cls) y = _reconstruct(x, rv, 1, memo) - memo[d] = y - _keep_alive(x, memo) # Make sure x lives at least as long as d + # If is its own copy, don't memoize. + if y is not x: + memo[d] = y + _keep_alive(x, memo) # Make sure x lives at least as long as d return y _deepcopy_dispatch = d = {} @@ -214,9 +216,10 @@ y = [] for a in x: y.append(deepcopy(a, memo)) - d = id(x) + # We're not going to put the tuple in the memo, but it's still important we + # check for it, in case the tuple contains recursive mutable structures. try: - return memo[d] + return memo[id(x)] except KeyError: pass for i in range(len(x)): @@ -225,7 +228,6 @@ break else: y = x - memo[d] = y return y d[tuple] = _deepcopy_tuple diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -321,9 +321,24 @@ def test_deepcopy_keepalive(self): memo = {} - x = 42 + x = [] y = copy.deepcopy(x, memo) - self.assertTrue(memo[id(x)] is x) + self.assertIs(memo[id(memo)][0], x) + + def test_deepcopy_dont_memo_immutable(self): + memo = {} + x = [1, 2, 3, 4] + y = copy.deepcopy(x, memo) + self.assertEqual(y, x) + # There's the entry for the new list, and the keep alive. + self.assertEqual(len(memo), 2) + + memo = {} + x = [(1, 2)] + y = copy.deepcopy(x, memo) + self.assertEqual(y, x) + # Tuples with immutable contents are immutable for deepcopy. + self.assertEqual(len(memo), 2) def test_deepcopy_inst_vanilla(self): class C: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,9 @@ Library ------- +- Issue #12422: In the copy module, don't store objects that are their own copy + in the memo dict. + - Issue #12303: Add sigwaitinfo() and sigtimedwait() to the signal module. - Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:47 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:47 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_add_more_ast_te?= =?utf8?q?sts_=28closes_=2311302=29?= Message-ID: http://hg.python.org/cpython/rev/3143cadb2f2d changeset: 71019:3143cadb2f2d branch: 2.7 parent: 71012:5d08c2a6274d user: Benjamin Peterson date: Mon Jun 27 17:46:06 2011 -0500 summary: add more ast tests (closes #11302) A patch from Vincent Legoll. files: Lib/test/test_ast.py | 178 +++++++++++++++++++++++++++++++ 1 files changed, 178 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -20,10 +20,24 @@ # These tests are compiled through "exec" # There should be atleast one test per statement exec_tests = [ + # None + "None", # FunctionDef "def f(): pass", + # FunctionDef with arg + "def f(a): pass", + # FunctionDef with arg and default value + "def f(a=0): pass", + # FunctionDef with varargs + "def f(*args): pass", + # FunctionDef with kwargs + "def f(**kwargs): pass", + # FunctionDef with all kind of args + "def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass", # ClassDef "class C:pass", + # ClassDef, new style class + "class C(object): pass", # Return "def f():return 1", # Delete @@ -68,6 +82,27 @@ "for a,b in c: pass", "[(a,b) for a,b in c]", "((a,b) for a,b in c)", + "((a,b) for (a,b) in c)", + # Multiline generator expression (test for .lineno & .col_offset) + """( + ( + Aa + , + Bb + ) + for + Aa + , + Bb in Cc + )""", + # dictcomp + "{a : b for w in x for m in p if g}", + # dictcomp with naked tuple + "{a : b for v,w in x}", + # setcomp + "{r for l in x if g}", + # setcomp with naked tuple + "{r for l,m in x}", ] # These are compiled through "single" @@ -80,6 +115,8 @@ # These are compiled through "eval" # It should test all expressions eval_tests = [ + # None + "None", # BoolOp "a and b", # BinOp @@ -90,6 +127,16 @@ "lambda:None", # Dict "{ 1:2 }", + # Empty dict + "{}", + # Set + "{None,}", + # Multiline dict (test for .lineno & .col_offset) + """{ + 1 + : + 2 + }""", # ListComp "[a for b in c if d]", # GeneratorExp @@ -114,8 +161,14 @@ "v", # List "[1,2,3]", + # Empty list + "[]", # Tuple "1,2,3", + # Tuple + "(1,2,3)", + # Empty tuple + "()", # Combination "a.b.c.d(a.b[1:2])", @@ -141,6 +194,23 @@ elif value is not None: self._assertTrueorder(value, parent_pos) + def test_AST_objects(self): + x = ast.AST() + self.assertEqual(x._fields, ()) + + with self.assertRaises(AttributeError): + x.vararg + + with self.assertRaises(AttributeError): + x.foobar = 21 + + with self.assertRaises(AttributeError): + ast.AST(lineno=2) + + with self.assertRaises(TypeError): + # "_ast.AST constructor takes 0 positional arguments" + ast.AST(2) + def test_snippets(self): for input, output, kind in ((exec_tests, exec_results, "exec"), (single_tests, single_results, "single"), @@ -169,7 +239,83 @@ self.assertTrue(issubclass(ast.comprehension, ast.AST)) self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_field_attr_existence(self): + for name, item in ast.__dict__.iteritems(): + if isinstance(item, type) and name != 'AST' and name[0].isupper(): + x = item() + if isinstance(x, ast.AST): + self.assertEqual(type(x._fields), tuple) + + def test_arguments(self): + x = ast.arguments() + self.assertEqual(x._fields, ('args', 'vararg', 'kwarg', 'defaults')) + + with self.assertRaises(AttributeError): + x.vararg + + x = ast.arguments(1, 2, 3, 4) + self.assertEqual(x.vararg, 2) + + def test_field_attr_writable(self): + x = ast.Num() + # We can assign to _fields + x._fields = 666 + self.assertEqual(x._fields, 666) + + def test_classattrs(self): + x = ast.Num() + self.assertEqual(x._fields, ('n',)) + + with self.assertRaises(AttributeError): + x.n + + x = ast.Num(42) + self.assertEqual(x.n, 42) + + with self.assertRaises(AttributeError): + x.lineno + + with self.assertRaises(AttributeError): + x.foobar + + x = ast.Num(lineno=2) + self.assertEqual(x.lineno, 2) + + x = ast.Num(42, lineno=0) + self.assertEqual(x.lineno, 0) + self.assertEqual(x._fields, ('n',)) + self.assertEqual(x.n, 42) + + self.assertRaises(TypeError, ast.Num, 1, 2) + self.assertRaises(TypeError, ast.Num, 1, 2, lineno=0) + + def test_module(self): + body = [ast.Num(42)] + x = ast.Module(body) + self.assertEqual(x.body, body) + def test_nodeclasses(self): + # Zero arguments constructor explicitely allowed + x = ast.BinOp() + self.assertEqual(x._fields, ('left', 'op', 'right')) + + # Random attribute allowed too + x.foobarbaz = 5 + self.assertEqual(x.foobarbaz, 5) + + n1 = ast.Num(1) + n3 = ast.Num(3) + addop = ast.Add() + x = ast.BinOp(n1, addop, n3) + self.assertEqual(x.left, n1) + self.assertEqual(x.op, addop) + self.assertEqual(x.right, n3) + + x = ast.BinOp(1, 2, 3) + self.assertEqual(x.left, 1) + self.assertEqual(x.op, 2) + self.assertEqual(x.right, 3) + x = ast.BinOp(1, 2, 3, lineno=0) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) @@ -178,6 +324,12 @@ # node raises exception when not given enough arguments self.assertRaises(TypeError, ast.BinOp, 1, 2) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4) + # node raises exception when not given enough arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, lineno=0) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0) # can set attributes through kwargs too x = ast.BinOp(left=1, op=2, right=3, lineno=0) @@ -186,8 +338,14 @@ self.assertEqual(x.right, 3) self.assertEqual(x.lineno, 0) + # Random kwargs also allowed + x = ast.BinOp(1, 2, 3, foobarbaz=42) + self.assertEqual(x.foobarbaz, 42) + + def test_no_fields(self): # this used to fail because Sub._fields was None x = ast.Sub() + self.assertEqual(x._fields, ()) def test_pickling(self): import pickle @@ -330,8 +488,15 @@ #### EVERYTHING BELOW IS GENERATED ##### exec_results = [ +('Module', [('Expr', (1, 0), ('Name', (1, 0), 'None', ('Load',)))]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Pass', (1, 9))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('Name', (1, 6), 'a', ('Param',))], None, None, []), [('Pass', (1, 10))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('Name', (1, 6), 'a', ('Param',))], None, None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], 'args', None, []), [('Pass', (1, 14))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, 'kwargs', []), [('Pass', (1, 17))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('Name', (1, 6), 'a', ('Param',)), ('Name', (1, 9), 'b', ('Param',)), ('Name', (1, 14), 'c', ('Param',)), ('Name', (1, 22), 'd', ('Param',)), ('Name', (1, 28), 'e', ('Param',))], 'args', 'kwargs', [('Num', (1, 11), 1), ('Name', (1, 16), 'None', ('Load',)), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 52))], [])]), ('Module', [('ClassDef', (1, 0), 'C', [], [('Pass', (1, 8))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [])]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -355,16 +520,26 @@ ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]), ('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]), ] eval_results = [ +('Expression', ('Name', (1, 0), 'None', ('Load',))), ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])), ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))), ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))), ('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, []), ('Name', (1, 7), 'None', ('Load',)))), ('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])), +('Expression', ('Dict', (1, 0), [], [])), +('Expression', ('Set', (1, 0), [('Name', (1, 1), 'None', ('Load',))])), +('Expression', ('Dict', (1, 0), [('Num', (2, 6), 1)], [('Num', (4, 10), 2)])), ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), @@ -376,7 +551,10 @@ ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), ('Expression', ('Name', (1, 0), 'v', ('Load',))), ('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('List', (1, 0), [], ('Load',))), ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), +('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('Tuple', (1, 0), [], ('Load',))), ('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), ] main() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:48 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E2=29=3A_add_more_ast_te?= =?utf8?q?sts_=28closes_=2311302=29?= Message-ID: http://hg.python.org/cpython/rev/e8d47cbe9b6f changeset: 71020:e8d47cbe9b6f branch: 3.2 parent: 71016:586745894ab8 user: Benjamin Peterson date: Mon Jun 27 17:46:06 2011 -0500 summary: add more ast tests (closes #11302) A patch from Vincent Legoll. files: Lib/test/test_ast.py | 180 +++++++++++++++++++++++++++++++ 1 files changed, 180 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -20,10 +20,24 @@ # These tests are compiled through "exec" # There should be atleast one test per statement exec_tests = [ + # None + "None", # FunctionDef "def f(): pass", + # FunctionDef with arg + "def f(a): pass", + # FunctionDef with arg and default value + "def f(a=0): pass", + # FunctionDef with varargs + "def f(*args): pass", + # FunctionDef with kwargs + "def f(**kwargs): pass", + # FunctionDef with all kind of args + "def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass", # ClassDef "class C:pass", + # ClassDef, new style class + "class C(object): pass", # Return "def f():return 1", # Delete @@ -64,6 +78,27 @@ "for a,b in c: pass", "[(a,b) for a,b in c]", "((a,b) for a,b in c)", + "((a,b) for (a,b) in c)", + # Multiline generator expression (test for .lineno & .col_offset) + """( + ( + Aa + , + Bb + ) + for + Aa + , + Bb in Cc + )""", + # dictcomp + "{a : b for w in x for m in p if g}", + # dictcomp with naked tuple + "{a : b for v,w in x}", + # setcomp + "{r for l in x if g}", + # setcomp with naked tuple + "{r for l,m in x}", ] # These are compiled through "single" @@ -76,6 +111,8 @@ # These are compiled through "eval" # It should test all expressions eval_tests = [ + # None + "None", # BoolOp "a and b", # BinOp @@ -86,6 +123,16 @@ "lambda:None", # Dict "{ 1:2 }", + # Empty dict + "{}", + # Set + "{None,}", + # Multiline dict (test for .lineno & .col_offset) + """{ + 1 + : + 2 + }""", # ListComp "[a for b in c if d]", # GeneratorExp @@ -108,8 +155,14 @@ "v", # List "[1,2,3]", + # Empty list + "[]", # Tuple "1,2,3", + # Tuple + "(1,2,3)", + # Empty tuple + "()", # Combination "a.b.c.d(a.b[1:2])", @@ -135,6 +188,23 @@ elif value is not None: self._assertTrueorder(value, parent_pos) + def test_AST_objects(self): + x = ast.AST() + self.assertEqual(x._fields, ()) + + with self.assertRaises(AttributeError): + x.vararg + + with self.assertRaises(AttributeError): + x.foobar = 21 + + with self.assertRaises(AttributeError): + ast.AST(lineno=2) + + with self.assertRaises(TypeError): + # "_ast.AST constructor takes 0 positional arguments" + ast.AST(2) + def test_snippets(self): for input, output, kind in ((exec_tests, exec_results, "exec"), (single_tests, single_results, "single"), @@ -162,7 +232,85 @@ self.assertTrue(issubclass(ast.comprehension, ast.AST)) self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_field_attr_existence(self): + for name, item in ast.__dict__.items(): + if isinstance(item, type) and name != 'AST' and name[0].isupper(): + x = item() + if isinstance(x, ast.AST): + self.assertEqual(type(x._fields), tuple) + + def test_arguments(self): + x = ast.arguments() + self.assertEqual(x._fields, ('args', 'vararg', 'varargannotation', + 'kwonlyargs', 'kwarg', 'kwargannotation', + 'defaults', 'kw_defaults')) + + with self.assertRaises(AttributeError): + x.vararg + + x = ast.arguments(*range(1, 9)) + self.assertEqual(x.vararg, 2) + + def test_field_attr_writable(self): + x = ast.Num() + # We can assign to _fields + x._fields = 666 + self.assertEqual(x._fields, 666) + + def test_classattrs(self): + x = ast.Num() + self.assertEqual(x._fields, ('n',)) + + with self.assertRaises(AttributeError): + x.n + + x = ast.Num(42) + self.assertEqual(x.n, 42) + + with self.assertRaises(AttributeError): + x.lineno + + with self.assertRaises(AttributeError): + x.foobar + + x = ast.Num(lineno=2) + self.assertEqual(x.lineno, 2) + + x = ast.Num(42, lineno=0) + self.assertEqual(x.lineno, 0) + self.assertEqual(x._fields, ('n',)) + self.assertEqual(x.n, 42) + + self.assertRaises(TypeError, ast.Num, 1, 2) + self.assertRaises(TypeError, ast.Num, 1, 2, lineno=0) + + def test_module(self): + body = [ast.Num(42)] + x = ast.Module(body) + self.assertEqual(x.body, body) + def test_nodeclasses(self): + # Zero arguments constructor explicitely allowed + x = ast.BinOp() + self.assertEqual(x._fields, ('left', 'op', 'right')) + + # Random attribute allowed too + x.foobarbaz = 5 + self.assertEqual(x.foobarbaz, 5) + + n1 = ast.Num(1) + n3 = ast.Num(3) + addop = ast.Add() + x = ast.BinOp(n1, addop, n3) + self.assertEqual(x.left, n1) + self.assertEqual(x.op, addop) + self.assertEqual(x.right, n3) + + x = ast.BinOp(1, 2, 3) + self.assertEqual(x.left, 1) + self.assertEqual(x.op, 2) + self.assertEqual(x.right, 3) + x = ast.BinOp(1, 2, 3, lineno=0) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) @@ -171,6 +319,12 @@ # node raises exception when not given enough arguments self.assertRaises(TypeError, ast.BinOp, 1, 2) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4) + # node raises exception when not given enough arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, lineno=0) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0) # can set attributes through kwargs too x = ast.BinOp(left=1, op=2, right=3, lineno=0) @@ -179,8 +333,14 @@ self.assertEqual(x.right, 3) self.assertEqual(x.lineno, 0) + # Random kwargs also allowed + x = ast.BinOp(1, 2, 3, foobarbaz=42) + self.assertEqual(x.foobarbaz, 42) + + def test_no_fields(self): # this used to fail because Sub._fields was None x = ast.Sub() + self.assertEqual(x._fields, ()) def test_pickling(self): import pickle @@ -332,8 +492,15 @@ #### EVERYTHING BELOW IS GENERATED ##### exec_results = [ +('Module', [('Expr', (1, 0), ('Name', (1, 0), 'None', ('Load',)))]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Pass', (1, 9))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None)], None, None, [], None, None, [], []), [('Pass', (1, 10))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None)], None, None, [], None, None, [('Num', (1, 8), 0)], []), [('Pass', (1, 12))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], 'args', None, [], None, None, [], []), [('Pass', (1, 14))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], 'kwargs', None, [], []), [('Pass', (1, 17))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None), ('arg', 'b', None), ('arg', 'c', None), ('arg', 'd', None), ('arg', 'e', None)], 'args', None, [], 'kwargs', None, [('Num', (1, 11), 1), ('Name', (1, 16), 'None', ('Load',)), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])], []), [('Pass', (1, 52))], [], None)]), ('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], None, None, [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -355,16 +522,26 @@ ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]), ('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]), ] eval_results = [ +('Expression', ('Name', (1, 0), 'None', ('Load',))), ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])), ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))), ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))), ('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, [], None, None, [], []), ('Name', (1, 7), 'None', ('Load',)))), ('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])), +('Expression', ('Dict', (1, 0), [], [])), +('Expression', ('Set', (1, 0), [('Name', (1, 1), 'None', ('Load',))])), +('Expression', ('Dict', (1, 0), [('Num', (2, 6), 1)], [('Num', (4, 10), 2)])), ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), @@ -375,7 +552,10 @@ ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), ('Expression', ('Name', (1, 0), 'v', ('Load',))), ('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('List', (1, 0), [], ('Load',))), ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), +('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('Tuple', (1, 0), [], ('Load',))), ('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), ] main() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:49 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiBtZXJnZSAzLjIgKCMxMTMwMik=?= Message-ID: http://hg.python.org/cpython/rev/323cf9acbccd changeset: 71021:323cf9acbccd parent: 71018:e24ad85e9608 parent: 71020:e8d47cbe9b6f user: Benjamin Peterson date: Mon Jun 27 17:50:14 2011 -0500 summary: merge 3.2 (#11302) files: Lib/test/test_ast.py | 180 +++++++++++++++++++++++++++++++ 1 files changed, 180 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -20,10 +20,24 @@ # These tests are compiled through "exec" # There should be atleast one test per statement exec_tests = [ + # None + "None", # FunctionDef "def f(): pass", + # FunctionDef with arg + "def f(a): pass", + # FunctionDef with arg and default value + "def f(a=0): pass", + # FunctionDef with varargs + "def f(*args): pass", + # FunctionDef with kwargs + "def f(**kwargs): pass", + # FunctionDef with all kind of args + "def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass", # ClassDef "class C:pass", + # ClassDef, new style class + "class C(object): pass", # Return "def f():return 1", # Delete @@ -67,6 +81,27 @@ "for a,b in c: pass", "[(a,b) for a,b in c]", "((a,b) for a,b in c)", + "((a,b) for (a,b) in c)", + # Multiline generator expression (test for .lineno & .col_offset) + """( + ( + Aa + , + Bb + ) + for + Aa + , + Bb in Cc + )""", + # dictcomp + "{a : b for w in x for m in p if g}", + # dictcomp with naked tuple + "{a : b for v,w in x}", + # setcomp + "{r for l in x if g}", + # setcomp with naked tuple + "{r for l,m in x}", ] # These are compiled through "single" @@ -79,6 +114,8 @@ # These are compiled through "eval" # It should test all expressions eval_tests = [ + # None + "None", # BoolOp "a and b", # BinOp @@ -89,6 +126,16 @@ "lambda:None", # Dict "{ 1:2 }", + # Empty dict + "{}", + # Set + "{None,}", + # Multiline dict (test for .lineno & .col_offset) + """{ + 1 + : + 2 + }""", # ListComp "[a for b in c if d]", # GeneratorExp @@ -111,8 +158,14 @@ "v", # List "[1,2,3]", + # Empty list + "[]", # Tuple "1,2,3", + # Tuple + "(1,2,3)", + # Empty tuple + "()", # Combination "a.b.c.d(a.b[1:2])", @@ -138,6 +191,23 @@ elif value is not None: self._assertTrueorder(value, parent_pos) + def test_AST_objects(self): + x = ast.AST() + self.assertEqual(x._fields, ()) + + with self.assertRaises(AttributeError): + x.vararg + + with self.assertRaises(AttributeError): + x.foobar = 21 + + with self.assertRaises(AttributeError): + ast.AST(lineno=2) + + with self.assertRaises(TypeError): + # "_ast.AST constructor takes 0 positional arguments" + ast.AST(2) + def test_snippets(self): for input, output, kind in ((exec_tests, exec_results, "exec"), (single_tests, single_results, "single"), @@ -165,7 +235,85 @@ self.assertTrue(issubclass(ast.comprehension, ast.AST)) self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_field_attr_existence(self): + for name, item in ast.__dict__.items(): + if isinstance(item, type) and name != 'AST' and name[0].isupper(): + x = item() + if isinstance(x, ast.AST): + self.assertEqual(type(x._fields), tuple) + + def test_arguments(self): + x = ast.arguments() + self.assertEqual(x._fields, ('args', 'vararg', 'varargannotation', + 'kwonlyargs', 'kwarg', 'kwargannotation', + 'defaults', 'kw_defaults')) + + with self.assertRaises(AttributeError): + x.vararg + + x = ast.arguments(*range(1, 9)) + self.assertEqual(x.vararg, 2) + + def test_field_attr_writable(self): + x = ast.Num() + # We can assign to _fields + x._fields = 666 + self.assertEqual(x._fields, 666) + + def test_classattrs(self): + x = ast.Num() + self.assertEqual(x._fields, ('n',)) + + with self.assertRaises(AttributeError): + x.n + + x = ast.Num(42) + self.assertEqual(x.n, 42) + + with self.assertRaises(AttributeError): + x.lineno + + with self.assertRaises(AttributeError): + x.foobar + + x = ast.Num(lineno=2) + self.assertEqual(x.lineno, 2) + + x = ast.Num(42, lineno=0) + self.assertEqual(x.lineno, 0) + self.assertEqual(x._fields, ('n',)) + self.assertEqual(x.n, 42) + + self.assertRaises(TypeError, ast.Num, 1, 2) + self.assertRaises(TypeError, ast.Num, 1, 2, lineno=0) + + def test_module(self): + body = [ast.Num(42)] + x = ast.Module(body) + self.assertEqual(x.body, body) + def test_nodeclasses(self): + # Zero arguments constructor explicitely allowed + x = ast.BinOp() + self.assertEqual(x._fields, ('left', 'op', 'right')) + + # Random attribute allowed too + x.foobarbaz = 5 + self.assertEqual(x.foobarbaz, 5) + + n1 = ast.Num(1) + n3 = ast.Num(3) + addop = ast.Add() + x = ast.BinOp(n1, addop, n3) + self.assertEqual(x.left, n1) + self.assertEqual(x.op, addop) + self.assertEqual(x.right, n3) + + x = ast.BinOp(1, 2, 3) + self.assertEqual(x.left, 1) + self.assertEqual(x.op, 2) + self.assertEqual(x.right, 3) + x = ast.BinOp(1, 2, 3, lineno=0) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) @@ -174,6 +322,12 @@ # node raises exception when not given enough arguments self.assertRaises(TypeError, ast.BinOp, 1, 2) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4) + # node raises exception when not given enough arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, lineno=0) + # node raises exception when given too many arguments + self.assertRaises(TypeError, ast.BinOp, 1, 2, 3, 4, lineno=0) # can set attributes through kwargs too x = ast.BinOp(left=1, op=2, right=3, lineno=0) @@ -182,8 +336,14 @@ self.assertEqual(x.right, 3) self.assertEqual(x.lineno, 0) + # Random kwargs also allowed + x = ast.BinOp(1, 2, 3, foobarbaz=42) + self.assertEqual(x.foobarbaz, 42) + + def test_no_fields(self): # this used to fail because Sub._fields was None x = ast.Sub() + self.assertEqual(x._fields, ()) def test_pickling(self): import pickle @@ -335,8 +495,15 @@ #### EVERYTHING BELOW IS GENERATED ##### exec_results = [ +('Module', [('Expr', (1, 0), ('Name', (1, 0), 'None', ('Load',)))]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Pass', (1, 9))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None)], None, None, [], None, None, [], []), [('Pass', (1, 10))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None)], None, None, [], None, None, [('Num', (1, 8), 0)], []), [('Pass', (1, 12))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], 'args', None, [], None, None, [], []), [('Pass', (1, 14))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], 'kwargs', None, [], []), [('Pass', (1, 17))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', 'a', None), ('arg', 'b', None), ('arg', 'c', None), ('arg', 'd', None), ('arg', 'e', None)], 'args', None, [], 'kwargs', None, [('Num', (1, 11), 1), ('Name', (1, 16), 'None', ('Load',)), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])], []), [('Pass', (1, 52))], [], None)]), ('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], None, None, [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, None, [], None, None, [], []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -360,16 +527,26 @@ ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]), ('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]), ] eval_results = [ +('Expression', ('Name', (1, 0), 'None', ('Load',))), ('Expression', ('BoolOp', (1, 0), ('And',), [('Name', (1, 0), 'a', ('Load',)), ('Name', (1, 6), 'b', ('Load',))])), ('Expression', ('BinOp', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Add',), ('Name', (1, 4), 'b', ('Load',)))), ('Expression', ('UnaryOp', (1, 0), ('Not',), ('Name', (1, 4), 'v', ('Load',)))), ('Expression', ('Lambda', (1, 0), ('arguments', [], None, None, [], None, None, [], []), ('Name', (1, 7), 'None', ('Load',)))), ('Expression', ('Dict', (1, 0), [('Num', (1, 2), 1)], [('Num', (1, 4), 2)])), +('Expression', ('Dict', (1, 0), [], [])), +('Expression', ('Set', (1, 0), [('Name', (1, 1), 'None', ('Load',))])), +('Expression', ('Dict', (1, 0), [('Num', (2, 6), 1)], [('Num', (4, 10), 2)])), ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), @@ -380,7 +557,10 @@ ('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), ('Expression', ('Name', (1, 0), 'v', ('Load',))), ('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('List', (1, 0), [], ('Load',))), ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), +('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), +('Expression', ('Tuple', (1, 0), [], ('Load',))), ('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), ] main() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:50 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:50 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogZml4IHdz?= Message-ID: http://hg.python.org/cpython/rev/797db80df567 changeset: 71022:797db80df567 branch: 2.7 parent: 71019:3143cadb2f2d user: Benjamin Peterson date: Mon Jun 27 17:51:18 2011 -0500 summary: fix ws files: Lib/test/test_ast.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -310,7 +310,7 @@ self.assertEqual(x.left, n1) self.assertEqual(x.op, addop) self.assertEqual(x.right, n3) - + x = ast.BinOp(1, 2, 3) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:50 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:50 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogZml4IHdz?= Message-ID: http://hg.python.org/cpython/rev/d238cc890e55 changeset: 71023:d238cc890e55 branch: 3.2 parent: 71020:e8d47cbe9b6f user: Benjamin Peterson date: Mon Jun 27 17:51:18 2011 -0500 summary: fix ws files: Lib/test/test_ast.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -305,7 +305,7 @@ self.assertEqual(x.left, n1) self.assertEqual(x.op, addop) self.assertEqual(x.right, n3) - + x = ast.BinOp(1, 2, 3) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:51:52 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:51:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/a4262a3494c0 changeset: 71024:a4262a3494c0 parent: 71021:323cf9acbccd parent: 71023:d238cc890e55 user: Benjamin Peterson date: Mon Jun 27 17:51:44 2011 -0500 summary: merge 3.2 files: Lib/test/test_ast.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -308,7 +308,7 @@ self.assertEqual(x.left, n1) self.assertEqual(x.op, addop) self.assertEqual(x.right, n3) - + x = ast.BinOp(1, 2, 3) self.assertEqual(x.left, 1) self.assertEqual(x.op, 2) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 00:54:40 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:54:40 +0200 Subject: [Python-checkins] =?utf8?q?devguide=3A_this_has_happened_to_me_tw?= =?utf8?q?ice_today?= Message-ID: http://hg.python.org/devguide/rev/607970c2b24b changeset: 436:607970c2b24b parent: 424:fe159fa6166f user: Benjamin Peterson date: Mon Jun 27 17:54:20 2011 -0500 summary: this has happened to me twice today files: patch.rst | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/patch.rst b/patch.rst --- a/patch.rst +++ b/patch.rst @@ -133,6 +133,9 @@ help revisions``. Just please make sure that you generate a **single, condensed** patch rather than a series of several changesets. +Also, please make sure your patch is whitespace normalized. ``make patchcheck`` +will check this for you. + Submitting ---------- -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Tue Jun 28 00:54:43 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:54:43 +0200 Subject: [Python-checkins] =?utf8?q?devguide_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/devguide/rev/54f788c62ef5 changeset: 437:54f788c62ef5 parent: 436:607970c2b24b parent: 435:63f3521fe8f8 user: Benjamin Peterson date: Mon Jun 27 17:54:43 2011 -0500 summary: merge heads files: committing.rst | 104 +++++++++++++++++++++++++++++++++--- docquality.rst | 10 +++ experts.rst | 1 + faq.rst | 102 +++++++++++++++++++++++++++++++++++- help.rst | 58 +++++++++++++++---- index.rst | 64 ++++++++++++++++++--- patch.rst | 4 +- 7 files changed, 304 insertions(+), 39 deletions(-) diff --git a/committing.rst b/committing.rst --- a/committing.rst +++ b/committing.rst @@ -3,8 +3,29 @@ Committing and Pushing Changes ============================== -.. TODO: include a checklist of items to be included in a commit? - e.g updated Misc/NEWS entry, tests, doc +Patch Checklist +--------------- + +Here's the simple patch checklist that ``make patchcheck`` will run through +on a system that uses the makefile to build Python: + +* Are there any whitespace problems in Python files? + (using Tools/scripts/reindent.py) +* Are there any whitespace problems in C files? +* Are there any whitespace problems in the documentation? + (using Tools/scripts/reindent-rst.py) +* Has the documentation been updated? +* Has the test suite been updated? +* Has ``Misc/NEWS`` been updated? +* Has ``Misc/ACKS`` been updated? +* Has the test suite been run? + +Note that the automated patch check can't actually *answer* all of these +questions, and even if it could, it still wouldn't know whether or not +those answers were appropriate. Aside from the whitespace checks, it is just +a memory aid to help with remembering the various elements that can go into +making a complete patch. + Commit Messages --------------- @@ -54,6 +75,10 @@ such as mq_ (Mercurial Queues), in order to maintain patches in a single local repository and to push them seamlessly when they are ready. +It can also be useful to keep a pristine clone of the main repository around, +as it allows simple reversion of all local changes (even "committed" ones) if +your local clone gets into a state you aren't happy with. + .. _Mercurial: http://www.hg-scm.org/ .. _mq: http://mercurial.selenic.com/wiki/MqExtension @@ -119,6 +144,41 @@ **will** break someone's code). If you are unsure if the breakage is worth it, ask on python-dev. +Third, ensure the patch is attributed correctly by adding the contributor's +name to ``Misc/ACKS`` if they aren't already there (and didn't add themselves +in their patch) and by mentioning "Patch by " in the ``Misc/NEWS`` entry +and the checkin message. If the patch has been heavily modified then "Initial +patch by " is an appropriate alternate wording. + +If you omit correct attribution in the initial checkin, then update ``ACKS`` +and ``NEWS`` in a subsequent checkin (don't worry about trying to fix the +original checkin message in that case). + + +Contributor Licensing Agreements +-------------------------------- + +It's unlikely bug fixes will require a `Contributor Licensing Agreement`_ +unless they touch a *lot* of code. For new features, it is preferable to +ask that the contributor submit a signed CLA to the PSF as the associated +comments, docstrings and documentation are far more likely to reach a +copyrightable standard. + +For Python sprints we now recommend collecting CLAs as a matter of course, as +the folks leading the sprints can then handle the task of scanning (or otherwise +digitising) the forms and passing them on to the PSF secretary. (Yes, we +realise this process is quite archaic. Yes, we're in the process of fixing +it. No, it's not fixed yet). + +As discussed on the PSF Contribution_ page, it is the CLA itself that gives +the PSF the necessary relicensing rights to redistribute contributions under +the Python license stack. This is an additional permission granted above and +beyond the normal permissions provided by the chosen open source license. + +.. _Contribution: http://www.python.org/psf/contrib/ +.. _Contributor Licensing Agreement: + http://www.python.org/psf/contrib/contrib-form/ + Forward-Porting --------------- @@ -135,7 +195,7 @@ Even when porting an already committed patch, you should **still** check the test suite runs successfully before committing the patch to another branch. Subtle differences between two branches sometimes make a patch bogus if - ported straightly. + ported without any modifications. Porting Within a Major Version @@ -222,8 +282,8 @@ There are various ways to achieve this, but here is a possible scenario: -* First do a clone of the public repository, whose working copy will be updated - to the ``default`` branch:: +* First do a clone of the public repository, whose working copy will be + updated to the ``default`` branch:: $ hg clone ssh://hg at hg.python.org/cpython py3k @@ -234,10 +294,11 @@ $ cd py3.2 $ hg update 3.2 -* If you also need the 3.1 branch, you can similarly clone it, either from - the ``py3.2`` or the ``py3k`` repository. It is suggested, though, that you - clone from ``py3.2`` as that it will force you to push changes back up your - clone chain so that you make sure to port changes to all proper versions. +* If you also need the 3.1 branch to work on security fixes, you can similarly + clone it, either from the ``py3.2`` or the ``py3k`` repository. It is + suggested, though, that you clone from ``py3.2`` as that it will force you + to push changes back up your clone chain so that you make sure to port + changes to all proper versions. * You can also clone a 2.7-dedicated repository from the ``py3k`` branch:: @@ -253,8 +314,25 @@ from the ``py3k`` repository will publish your changes in the public repository. +When working with this kind of arrangement, it can be useful to have a simple +script that runs the necessary commands to update all branches with upstream +changes:: + + cd ~/py3k + hg pull -u + cd ~/py3.2 + hg pull -u + cd ~/py2.7 + hg pull -u + +Only the first of those updates will touch the network - the latter two will +just transfer the changes locally between the relevant repositories. + If you want, you can later :ref:`change the flow of changes ` implied -by the cloning of repositories. +by the cloning of repositories. For example, you may choose to add a separate +``sandbox`` repository for experimental code (potentially published somewhere +other than python.org) or an additional pristine repository that is +never modified locally. Differences with ``svnmerge`` @@ -354,8 +432,14 @@ mywork $ hg merge default +Rather than using a clone on ``python.org`` (which isn't particularly useful +for collaboration with folks that don't already have CPython commit rights), +Bitbucket_ also maintain an `up to date clone`_ of the main ``cpython`` +repository that can be used as the basis for a new clone or patch queue. .. _named branch: http://mercurial.selenic.com/wiki/NamedBranches +.. _Bitbucket: http://www.bitbucket.org +.. _up to date clone: https://bitbucket.org/mirror/cpython/overview Uploading a patch for review diff --git a/docquality.rst b/docquality.rst --- a/docquality.rst +++ b/docquality.rst @@ -66,3 +66,13 @@ to finish, filing issues in the issue tracker for each problem you find. Don't file a single issue for an entire section containing multiple problems as that makes it harder to break the work up for multiple people to help with. + + +Helping with the Developer's Guide +---------------------------------- + +This developer guide lives in a `separate source code repository`_, but is +otherwise managed using the same process as is used for the main Python +documentation. + +.. _separate source code repository: http://hg.python.org/devguide diff --git a/experts.rst b/experts.rst --- a/experts.rst +++ b/experts.rst @@ -299,6 +299,7 @@ context managers ncoghlan data formats mark.dickinson, georg.brandl database lemburg +devguide ncoghlan, eric.araujo documentation georg.brandl, ezio.melotti, eric.araujo GUI i18n lemburg, eric.araujo diff --git a/faq.rst b/faq.rst --- a/faq.rst +++ b/faq.rst @@ -8,8 +8,108 @@ .. contents:: :local: + +Communications +============== + + +Where should I ask general Python questions? +-------------------------------------------- + +General Python questions should still go to `python-list`_ or `python-tutor`_ +or similar resources, such as StackOverflow_ or ``#python`` on IRC. + +.. _python-list: http://mail.python.org/mailman/listinfo/python-list +.. _python-tutor: http://mail.python.org/mailman/listinfo/python-tutor +.. _StackOverflow: http://stackoverflow.com/ + + +Where should I suggest new features and language changes? +--------------------------------------------------------- + +The `python-ideas`_ mailing list is specifically intended for discussion of +new features and language changes. Please don't be disappointed if your +idea isn't met with universal approval: as the long list of Rejected and +Withdrawn PEPs in the `PEP Index`_ attests, and as befits a reasonably mature +programming language, getting significant changes into Python isn't a simple +task. + +If the idea is reasonable, someone will suggest posting it as a feature +request on the `issue tracker`_. + +.. _python-ideas: http://mail.python.org/mailman/listinfo/python-ideas +.. _issue tracker: http://bugs.python.org +.. _PEP Index: http://www.python.org/dev/peps + + +Where should I ask general questions about contributing to CPython? +------------------------------------------------------------------- + +The `Python Mentors`_ program is specifically about encouraging +developers and others that would like to contribute to Python development in +general, rather than necessarily being focused on one particular issue. + +.. _Python Mentors: http://pythonmentors.com + + +Where should I report specific problems? +---------------------------------------- + +Specific problems should be posted to the `issue tracker`_. + + +What if I'm not sure it is a bug? +--------------------------------- + +The general Python help locations listed above are the best place to start +with that kind of question. If they agree it looks like a bug, then the +next step is to either post it to the `issue tracker`_ or else to ask further +on the core development mailing list, `python-dev`_. + +.. _python-dev: http://mail.python.org/mailman/listinfo/python-dev + + +What if I disagree with an issue resolution on the tracker? +----------------------------------------------------------- + +First, take some time to consider any comments made in association with the +resolution of the tracker issue. On reflection, they may seem more reasonable +than they first appeared. + +If you still feel the resolution is incorrect, then raise the question on +`python-dev`_. If the consensus there supports the disputed resolution, please +take any further objections to `python-ideas`_ (or some other forum). Further +argument on `python-dev`_ after a consensus has been reached amongst the core +developers is unlikely to win any converts. + + +How do I tell who is and isn't a core developer? +------------------------------------------------ + +You can check their name against the `full list of developers`_ with commit +rights to the main source control repository. + +On the `issue tracker`_, most core developers will have the Python logo +appear next to their name. + +.. _full list of developers: http://www.python.org/dev/committers + + +What standards of behaviour are expected in these communication channels? +------------------------------------------------------------------------- + +We try to foster environments of mutual respect, tolerance and encouragement, +as described in the PSF's `Diversity Statement`_. Abiding by the guidelines +in this document and asking questions or posting suggestions in the +appropriate channels are an excellent way to get started on the mutual respect +part, greatly increasing the chances of receiving tolerance and encouragement +in return. + +.. _Diversity Statement: http://www.python.org/psf/diversity/ + + Version Control -================================== +=============== Where can I learn about the version control system used, Mercurial (hg)? ------------------------------------------------------------------------------- diff --git a/help.rst b/help.rst --- a/help.rst +++ b/help.rst @@ -5,31 +5,32 @@ If you are working on Python it is very possible you will come across an issue where you need some assistance to solve it (this happens to core developers -all the time). Below are some options on getting help. +all the time). -If the question involves process or tool usage then please check other parts of -this guide first as it should answer your question. +Should you require help, there are a :ref:`variety of options available +` to seek assistance. If the question involves process or tool +usage then please check the rest of this guide first (especially the +:ref:`FAQ`) as it should answer your question. -Ask (#)python-dev +Ask #python-dev ----------------- -You have two avenues of communication out of the :ref:`myriad of options -available `. If you are comfortable with IRC you can try asking -on ``#python-dev`` (on the `freenode `_ network). -Typically there are a couple of experienced developers, ranging from -triagers to core developers, who can answer questions about developing for -Python. If you prefer email you can ask the `python-dev mailing-list -`_ for help with your -question. Just remember that both avenues are for questions involving the -development *of* Python, **not** for development *with* Python. +If you are comfortable with IRC you can try asking on ``#python-dev`` (on +the `freenode`_ network). Typically there are a number of experienced +developers, ranging from triagers to core developers, who can answer +questions about developing for Python. Just remember that ``#python-dev`` +is for questions involving the development *of* Python whereas ``#python`` +is for questions concerning development *with* Python. + +.. _freenode: http://freenode.net/ File a Bug ---------- If you strongly suspect you have stumbled on a bug (be it in the build -process, in the test suite, or in other areas), then open a issue on the +process, in the test suite, or in other areas), then open an issue on the `issue tracker`_. As with every bug report it is strongly advised that you detail which conditions triggered it (including the OS name and version, and what you were trying to do), as well as the exact error message you @@ -37,3 +38,32 @@ .. _issue tracker: http://bugs.python.org + +Mailing Lists +------------- + +Further options for seeking assistance include the `python-ideas`_ and +`python-dev`_ mailing lists. Python-ideas contains discussion of speculative +Python language ideas for possible inclusion into the language. If an idea +gains traction it can then be discussed and honed to the point of becoming a +solid proposal and presented on python-dev. Python-dev contains discussion +of current Python design issues, release mechanics, and maintenance of +existing releases. As with ``#python-dev``, these mailing lists are for +questions involving the development *of* Python, **not** for development +*with* Python. + +.. _python-ideas: http://mail.python.org/mailman/listinfo/python-ideas +.. _python-dev: http://mail.python.org/mailman/listinfo/python-dev + + +Core Mentorship +--------------- + +If you are interested in improving Python and contributing to its development, +but don?t yet feel entirely comfortable with the public channels mentioned +above, `Python Mentors`_ are here to help you. Python is fortunate to have a +community of volunteer core developers willing to mentor anyone wishing to +contribute code, work on bug fixes or improve documentation. Everyone is +welcomed and encouraged to contribute. + +.. _Python Mentors: http://pythonmentors.com diff --git a/index.rst b/index.rst --- a/index.rst +++ b/index.rst @@ -50,18 +50,14 @@ ------------ We encourage everyone to contribute to Python and that's why we have put up -this developer's guide. You **should** read the following documents in -the order provided. You can stop where you feel comfortable and begin -contributing immediately without reading and understanding these documents all -at once, but please do not skip around within the documentation as everything -is written assuming preceding documentation has been read. +this developer's guide. If you still have questions after reviewing the +material in this guide, then the `Python Mentors`_ group is available to help +guide new contributors through the process. The :doc:`Developer FAQ ` is +another useful source of information. -You can, *however*, read the :doc:`FAQ ` at any point! +Guide for contributing to Python: * :doc:`setup` -* Coding style guides - * `PEP 7`_ (Style Guide for C Code) - * `PEP 8`_ (Style Guide for Python Code) * :doc:`help` * :doc:`patch` * :doc:`runtests` @@ -82,14 +78,54 @@ * :doc:`devcycle` * :doc:`buildbots` +It is **recommended** that the above documents be read in the order listed. +You can stop where you feel comfortable and begin contributing immediately +without reading and understanding these documents all at once. If you do +choose to skip around within the documentation, be aware that it is written +assuming preceding documentation has been read so you may find it necessary +to backtrack to fill in missing concepts and terminology. + Proposing changes to Python itself ---------------------------------- +Improving Python's code, documentation and tests are ongoing tasks that are +never going to be "finished", as Python operates as part of an ever-evolving +system of technology. An even more challenging ongoing task than these +necessary maintenance activities is finding ways to make Python, in the form +of the standard library and the language definition, an even better tool in a +developer's toolkit. + +While these kinds of change are much rarer than those described above, they do +happen and that process is also described as part of this guide: + * :doc:`stdlibchanges` * :doc:`langchanges` +Other Interpreter Implementations +--------------------------------- + +This guide is specifically for contributing to the Python reference +interpreter, also known as CPython (while most of the standard library is +written in Python, the interpreter core is written in C and integrates most +easily with the C and C++ ecosystems). + +There are other Python implementations, each with a different focus. +Like CPython, they always have more things they would like to do than they +have developers to work on them. Some major example that may of interest are: + +* PyPy_: A Python interpreter focused on high speed (JIT-compiled) operation + on major platforms +* Jython_: A Python interpreter focused on good integration with the Java + Virtual Machine (JVM) environment +* IronPython_: A Python interpreter focused on good integration with the + Common Language Runtime (CLR) provided by .NET and Mono +* Stackless_: A Python interpreter focused on providing lightweight + microthreads while remaining largely compatible with CPython specific + extension modules + + .. _resources: @@ -99,6 +135,9 @@ * Anyone can checkout this guide from http://hg.python.org/devguide/. Core developers should use ssh://hg at hg.python.org/devguide instead, so that they can push back their edits to the server. +* Coding style guides + * :PEP:`7` (Style Guide for C Code) + * :PEP:`8` (Style Guide for Python Code) * `Issue tracker `_ * `Meta tracker `_ (issue tracker for the issue tracker) @@ -126,9 +165,12 @@ .. _Firefox search engine plug-in: http://www.python.org/dev/searchplugin/ .. _Misc directory: http://hg.python.org/cpython/file/tip/Misc .. _PEPs: http://www.python.org/dev/peps -.. _PEP 7: http://www.python.org/dev/peps/pep-0007 -.. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _python.org maintenance: http://python.org/dev/pydotorg/ +.. _Python Mentors: http://pythonmentors.com/ +.. _PyPy: http://www.pypy.org/ +.. _Jython: http://www.jython.org/ +.. _IronPython: http://ironpython.net/ +.. _Stackless: http://www.stackless.com/ Indices and tables diff --git a/patch.rst b/patch.rst --- a/patch.rst +++ b/patch.rst @@ -69,7 +69,7 @@ do to help ensure that your patch is accepted. First, make sure to follow Python's style guidelines. For Python code you -should follow `PEP 8`_, and for C code you should follow `PEP 7`_. If you have +should follow :PEP:`8`, and for C code you should follow :PEP:`7`. If you have one or two discrepencies those can be fixed by the core developer who commits your patch. But if you have systematic deviations from the style guides your patch will be put on hold until you fix the formatting issues. @@ -104,8 +104,6 @@ .. _contributor form: http://www.python.org/psf/contrib/ -.. _PEP 7: http://www.python.org/dev/peps/pep-0007 -.. _PEP 8: http://www.python.org/dev/peps/pep-0008 .. _Python Software Foundation: http://www.python.org/psf/ -- Repository URL: http://hg.python.org/devguide From python-checkins at python.org Tue Jun 28 00:59:38 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 00:59:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_svn_support?= Message-ID: http://hg.python.org/cpython/rev/45e7c067332e changeset: 71025:45e7c067332e user: Benjamin Peterson date: Mon Jun 27 17:59:45 2011 -0500 summary: remove svn support files: Tools/scripts/patchcheck.py | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -38,9 +38,6 @@ if os.path.isdir('.hg'): vcs = 'hg' cmd = 'hg status --added --modified --no-status' - elif os.path.isdir('.svn'): - vcs = 'svn' - cmd = 'svn status --quiet --non-interactive --ignore-externals' else: sys.exit('need a checkout to get modified files') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 01:25:04 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 01:25:04 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_general_cleaning_up?= Message-ID: http://hg.python.org/cpython/rev/39fadb0255cd changeset: 71026:39fadb0255cd user: Benjamin Peterson date: Mon Jun 27 18:25:06 2011 -0500 summary: general cleaning up files: Tools/scripts/patchcheck.py | 14 +++----------- 1 files changed, 3 insertions(+), 11 deletions(-) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -36,7 +36,6 @@ def changed_files(): """Get the list of changed or added files from the VCS.""" if os.path.isdir('.hg'): - vcs = 'hg' cmd = 'hg status --added --modified --no-status' else: sys.exit('need a checkout to get modified files') @@ -44,12 +43,7 @@ st = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) try: st.wait() - if vcs == 'hg': - return [x.decode().rstrip() for x in st.stdout] - else: - output = (x.decode().rstrip().rsplit(None, 1)[-1] - for x in st.stdout if x[0] in b'AM') - return set(path for path in output if os.path.isfile(path)) + return [x.decode().rstrip() for x in st.stdout] finally: st.stdout.close() @@ -69,10 +63,8 @@ def normalize_whitespace(file_paths): """Make sure that the whitespace for .py files have been normalized.""" reindent.makebackup = False # No need to create backups. - fixed = [] - for path in (x for x in file_paths if x.endswith('.py')): - if reindent.check(path): - fixed.append(path) + fixed = [path for path in file_paths if path.endswith('.py') and + reindent.check(path)] return fixed -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Tue Jun 28 05:07:31 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 28 Jun 2011 05:07:31 +0200 Subject: [Python-checkins] Daily reference leaks (39fadb0255cd): sum=244 Message-ID: results for 39fadb0255cd on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 test_pyexpat leaked [0, 0, -56] references, sum=-56 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogQ6IObn', '-x'] From python-checkins at python.org Tue Jun 28 08:20:34 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 08:20:34 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEwNzM2?= =?utf8?q?=3A_Fix_test=5Fttk_test=5Fwidgets_failures_with_Cocoa_Tk_8=2E5?= =?utf8?q?=2E9?= Message-ID: http://hg.python.org/cpython/rev/4a0b929b5c3d changeset: 71027:4a0b929b5c3d branch: 2.7 parent: 71022:797db80df567 user: Ned Deily date: Mon Jun 27 23:09:31 2011 -0700 summary: Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 on Mac OS X. (Patch by Ronald Oussoren) files: Lib/lib-tk/test/test_ttk/test_widgets.py | 20 +++++++++-- Misc/NEWS | 3 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/lib-tk/test/test_ttk/test_widgets.py b/Lib/lib-tk/test/test_ttk/test_widgets.py --- a/Lib/lib-tk/test/test_ttk/test_widgets.py +++ b/Lib/lib-tk/test/test_ttk/test_widgets.py @@ -2,6 +2,7 @@ import Tkinter import ttk from test.test_support import requires, run_unittest +import sys import support from test_functions import MockTclObj, MockStateSpec @@ -560,11 +561,19 @@ self.nb.pack() self.nb.wait_visibility() - self.assertEqual(self.nb.tab('@5,5'), self.nb.tab('current')) + if sys.platform == 'darwin': + tb_idx = "@20,5" + else: + tb_idx = "@5,5" + self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current')) for i in range(5, 100, 5): - if self.nb.tab('@%d, 5' % i, text=None) == 'a': - break + try: + if self.nb.tab('@%d, 5' % i, text=None) == 'a': + break + except Tkinter.TclError: + pass + else: self.fail("Tab with text 'a' not found") @@ -721,7 +730,10 @@ self.nb.enable_traversal() self.nb.focus_force() support.simulate_mouse_click(self.nb, 5, 5) - self.nb.event_generate('') + if sys.platform == 'darwin': + self.nb.event_generate('') + else: + self.nb.event_generate('') self.assertEqual(self.nb.select(), str(self.child1)) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Tests ----- +- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 + on Mac OS X. (Patch by Ronald Oussoren) + - Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, iso2022_kr). -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 08:20:35 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 08:20:35 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEwNzM2?= =?utf8?q?=3A_Fix_test=5Fttk_test=5Fwidgets_failures_with_Cocoa_Tk_8=2E5?= =?utf8?q?=2E9?= Message-ID: http://hg.python.org/cpython/rev/570cdef34066 changeset: 71028:570cdef34066 branch: 3.2 parent: 71023:d238cc890e55 user: Ned Deily date: Mon Jun 27 23:12:20 2011 -0700 summary: Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 on Mac OS X. (Patch by Ronald Oussoren) files: Lib/tkinter/test/test_ttk/test_widgets.py | 20 ++++++++-- Misc/NEWS | 3 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -3,6 +3,7 @@ import os from tkinter import ttk from test.support import requires, run_unittest +import sys import tkinter.test.support as support from tkinter.test.test_ttk.test_functions import MockTclObj, MockStateSpec @@ -561,11 +562,19 @@ self.nb.pack() self.nb.wait_visibility() - self.assertEqual(self.nb.tab('@5,5'), self.nb.tab('current')) + if sys.platform == 'darwin': + tb_idx = "@20,5" + else: + tb_idx = "@5,5" + self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current')) for i in range(5, 100, 5): - if self.nb.tab('@%d, 5' % i, text=None) == 'a': - break + try: + if self.nb.tab('@%d, 5' % i, text=None) == 'a': + break + except tkinter.TclError: + pass + else: self.fail("Tab with text 'a' not found") @@ -722,7 +731,10 @@ self.nb.enable_traversal() self.nb.focus_force() support.simulate_mouse_click(self.nb, 5, 5) - self.nb.event_generate('') + if sys.platform == 'darwin': + self.nb.event_generate('') + else: + self.nb.event_generate('') self.assertEqual(self.nb.select(), str(self.child1)) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,9 @@ Tests ----- +- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 + on Mac OS X. (Patch by Ronald Oussoren) + - Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, iso2022_kr). -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 08:20:36 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 08:20:36 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=2310736=3A_Fix_test=5Fttk_test=5Fwidgets_failures_wit?= =?utf8?q?h_Cocoa_Tk_8=2E5=2E9?= Message-ID: http://hg.python.org/cpython/rev/b7c61000ceec changeset: 71029:b7c61000ceec parent: 71026:39fadb0255cd parent: 71028:570cdef34066 user: Ned Deily date: Mon Jun 27 23:18:45 2011 -0700 summary: Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 2.8 + on Mac OS X. (Patch by Ronald Oussoren) files: Lib/tkinter/test/test_ttk/test_widgets.py | 20 ++++++++-- Misc/NEWS | 3 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -3,6 +3,7 @@ import os from tkinter import ttk from test.support import requires, run_unittest +import sys import tkinter.test.support as support from tkinter.test.test_ttk.test_functions import MockTclObj, MockStateSpec @@ -561,11 +562,19 @@ self.nb.pack() self.nb.wait_visibility() - self.assertEqual(self.nb.tab('@5,5'), self.nb.tab('current')) + if sys.platform == 'darwin': + tb_idx = "@20,5" + else: + tb_idx = "@5,5" + self.assertEqual(self.nb.tab(tb_idx), self.nb.tab('current')) for i in range(5, 100, 5): - if self.nb.tab('@%d, 5' % i, text=None) == 'a': - break + try: + if self.nb.tab('@%d, 5' % i, text=None) == 'a': + break + except tkinter.TclError: + pass + else: self.fail("Tab with text 'a' not found") @@ -722,7 +731,10 @@ self.nb.enable_traversal() self.nb.focus_force() support.simulate_mouse_click(self.nb, 5, 5) - self.nb.event_generate('') + if sys.platform == 'darwin': + self.nb.event_generate('') + else: + self.nb.event_generate('') self.assertEqual(self.nb.select(), str(self.child1)) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -908,6 +908,9 @@ Tests ----- +- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 + 2.8 + on Mac OS X. (Patch by Ronald Oussoren) + - Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, iso2022_kr). -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:13:50 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:13:50 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzg3NDY6?= =?utf8?q?_Correct_faulty_configure_checks_so_that_os=2Echflags=28=29_and?= Message-ID: http://hg.python.org/cpython/rev/abfe28e7e5cd changeset: 71030:abfe28e7e5cd branch: 2.7 parent: 71027:4a0b929b5c3d user: Ned Deily date: Mon Jun 27 23:41:53 2011 -0700 summary: Issue #8746: Correct faulty configure checks so that os.chflags() and os.lchflags() are once again built on systems that support these functions (*BSD and OS X). Also add new stat file flags for OS X (UF_HIDDEN and UF_COMPRESSED). Also add additional tests for os.chflags() and os.lchflags(). (Tests by Garrett Cooper) files: Doc/library/os.rst | 2 + Doc/library/stat.rst | 12 +++++- Lib/stat.py | 2 + Lib/test/test_posix.py | 58 ++++++++++++++++++++++++----- Misc/ACKS | 1 + Misc/NEWS | 11 +++++ configure | 8 ++-- configure.in | 12 +++--- pyconfig.h.in | 7 ++- 9 files changed, 88 insertions(+), 25 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1014,6 +1014,8 @@ * :data:`stat.UF_APPEND` * :data:`stat.UF_OPAQUE` * :data:`stat.UF_NOUNLINK` + * :data:`stat.UF_COMPRESSED` + * :data:`stat.UF_HIDDEN` * :data:`stat.SF_ARCHIVED` * :data:`stat.SF_IMMUTABLE` * :data:`stat.SF_APPEND` diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -304,13 +304,21 @@ The file may only be appended to. +.. data:: UF_OPAQUE + + The directory is opaque when viewed through a union stack. + .. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_OPAQUE +.. data:: UF_COMPRESSED - The directory is opaque when viewed through a union stack. + The file is stored compressed (Mac OS X 10.6+). + +.. data:: UF_HIDDEN + + The file should not be displayed in a GUI (Mac OS X 10.5+). .. data:: SF_ARCHIVED diff --git a/Lib/stat.py b/Lib/stat.py --- a/Lib/stat.py +++ b/Lib/stat.py @@ -87,6 +87,8 @@ UF_APPEND = 0x00000004 UF_OPAQUE = 0x00000008 UF_NOUNLINK = 0x00000010 +UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed +UF_HIDDEN = 0x00008000 # OS X: file should not be displayed SF_ARCHIVED = 0x00010000 SF_IMMUTABLE = 0x00020000 SF_APPEND = 0x00040000 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -11,10 +11,12 @@ import os import pwd import shutil +import stat import sys import unittest import warnings +_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp') warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) @@ -25,9 +27,11 @@ # create empty file fp = open(test_support.TESTFN, 'w+') fp.close() + self.teardown_files = [ test_support.TESTFN ] def tearDown(self): - os.unlink(test_support.TESTFN) + for teardown_file in self.teardown_files: + os.unlink(teardown_file) def testNoArgFunctions(self): # test posix functions which take no arguments and have @@ -258,7 +262,7 @@ def test_lchown(self): os.unlink(test_support.TESTFN) # create a symlink - os.symlink('/tmp/dummy-symlink-target', test_support.TESTFN) + os.symlink(_DUMMY_SYMLINK, test_support.TESTFN) self._test_all_chown_common(posix.lchown, test_support.TESTFN) def test_chdir(self): @@ -315,17 +319,49 @@ posix.utime(test_support.TESTFN, (int(now), int(now))) posix.utime(test_support.TESTFN, (now, now)) + def _test_chflags_regular_file(self, chflags_func, target_file): + st = os.stat(target_file) + self.assertTrue(hasattr(st, 'st_flags')) + chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE) + try: + new_st = os.stat(target_file) + self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags) + try: + fd = open(target_file, 'w+') + except IOError as e: + self.assertEqual(e.errno, errno.EPERM) + finally: + posix.chflags(target_file, st.st_flags) + + @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()') def test_chflags(self): - if hasattr(posix, 'chflags'): - st = os.stat(test_support.TESTFN) - if hasattr(st, 'st_flags'): - posix.chflags(test_support.TESTFN, st.st_flags) + self._test_chflags_regular_file(posix.chflags, test_support.TESTFN) - def test_lchflags(self): - if hasattr(posix, 'lchflags'): - st = os.stat(test_support.TESTFN) - if hasattr(st, 'st_flags'): - posix.lchflags(test_support.TESTFN, st.st_flags) + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_regular_file(self): + self._test_chflags_regular_file(posix.lchflags, test_support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_symlink(self): + testfn_st = os.stat(test_support.TESTFN) + + self.assertTrue(hasattr(testfn_st, 'st_flags')) + + os.symlink(test_support.TESTFN, _DUMMY_SYMLINK) + self.teardown_files.append(_DUMMY_SYMLINK) + dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + posix.lchflags(_DUMMY_SYMLINK, + dummy_symlink_st.st_flags | stat.UF_IMMUTABLE) + try: + new_testfn_st = os.stat(test_support.TESTFN) + new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags) + self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE, + new_dummy_symlink_st.st_flags) + finally: + posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags) def test_getcwd_long_pathnames(self): if hasattr(posix, 'getcwd'): diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -162,6 +162,7 @@ Juan Jos? Conti Matt Conway David M. Cooke +Garrett Cooper Greg Copeland Aldo Cortesi David Costanzo diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -53,9 +53,20 @@ constructor has failed, e.g. because of an undeclared keyword argument. Patch written by Oleg Oshmyan. +Build +----- + +- Issue #8746: Correct faulty configure checks so that os.chflags() and + os.lchflags() are once again built on systems that support these + functions (*BSD and OS X). Also add new stat file flags for OS X + (UF_HIDDEN and UF_COMPRESSED). + Tests ----- +- Issue #8746: Add additional tests for os.chflags() and os.lchflags(). + Patch by Garrett Cooper. + - Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 on Mac OS X. (Patch by Ronald Oussoren) diff --git a/configure b/configure --- a/configure +++ b/configure @@ -10073,7 +10073,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -10082,7 +10082,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_chflags=yes @@ -10122,7 +10122,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -10131,7 +10131,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_lchflags=yes diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2839,7 +2839,7 @@ # On Tru64, chflags seems to be present, but calling it will # exit Python AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2848,7 +2848,7 @@ return 1; return 0; } -]]])], +]])], [ac_cv_have_chflags=yes], [ac_cv_have_chflags=no], [ac_cv_have_chflags=cross]) @@ -2857,11 +2857,11 @@ AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) fi if test "$ac_cv_have_chflags" = yes ; then - AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.]) + AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.]) fi AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2870,13 +2870,13 @@ return 1; return 0; } -]]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) +]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) ]) if test "$ac_cv_have_lchflags" = cross ; then AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) fi if test "$ac_cv_have_lchflags" = yes ; then - AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the `lchflags' function.]) + AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.]) fi dnl Check if system zlib has *Copy() functions diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -100,7 +100,7 @@ /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL -/* Define to 1 if you have the `chflags' function. */ +/* Define to 1 if you have the 'chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if you have the `chown' function. */ @@ -391,7 +391,7 @@ Solaris and Linux, the necessary defines are already defined.) */ #undef HAVE_LARGEFILE_SUPPORT -/* Define to 1 if you have the `lchflags' function. */ +/* Define to 1 if you have the 'lchflags' function. */ #undef HAVE_LCHFLAGS /* Define to 1 if you have the `lchmod' function. */ @@ -1137,6 +1137,9 @@ /* This must be defined on some systems to enable large file support. */ #undef _LARGEFILE_SOURCE +/* This must be defined on AIX systems to enable large file support. */ +#undef _LARGE_FILES + /* Define to 1 if on MINIX. */ #undef _MINIX -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:13:51 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:13:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzg3NDY6?= =?utf8?q?_Correct_faulty_configure_checks_so_that_os=2Echflags=28=29_and?= Message-ID: http://hg.python.org/cpython/rev/529e26aa4fa3 changeset: 71031:529e26aa4fa3 branch: 3.2 parent: 71028:570cdef34066 user: Ned Deily date: Tue Jun 28 00:00:28 2011 -0700 summary: Issue #8746: Correct faulty configure checks so that os.chflags() and os.lchflags() are once again built on systems that support these functions (*BSD and OS X). Also add new stat file flags for OS X (UF_HIDDEN and UF_COMPRESSED). Also add additional tests for os.chflags() and os.lchflags(). (Tests by Garrett Cooper) files: Doc/library/os.rst | 2 + Doc/library/stat.rst | 12 +++++- Lib/stat.py | 2 + Lib/test/test_posix.py | 57 ++++++++++++++++++++++++----- Misc/ACKS | 1 + Misc/NEWS | 8 ++++ configure | 8 ++-- configure.in | 12 +++--- pyconfig.h.in | 7 ++- 9 files changed, 84 insertions(+), 25 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -989,6 +989,8 @@ * :data:`stat.UF_APPEND` * :data:`stat.UF_OPAQUE` * :data:`stat.UF_NOUNLINK` + * :data:`stat.UF_COMPRESSED` + * :data:`stat.UF_HIDDEN` * :data:`stat.SF_ARCHIVED` * :data:`stat.SF_IMMUTABLE` * :data:`stat.SF_APPEND` diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -307,13 +307,21 @@ The file may only be appended to. +.. data:: UF_OPAQUE + + The directory is opaque when viewed through a union stack. + .. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_OPAQUE +.. data:: UF_COMPRESSED - The directory is opaque when viewed through a union stack. + The file is stored compressed (Mac OS X 10.6+). + +.. data:: UF_HIDDEN + + The file should not be displayed in a GUI (Mac OS X 10.5+). .. data:: SF_ARCHIVED diff --git a/Lib/stat.py b/Lib/stat.py --- a/Lib/stat.py +++ b/Lib/stat.py @@ -87,6 +87,8 @@ UF_APPEND = 0x00000004 UF_OPAQUE = 0x00000008 UF_NOUNLINK = 0x00000010 +UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed +UF_HIDDEN = 0x00008000 # OS X: file should not be displayed SF_ARCHIVED = 0x00010000 SF_IMMUTABLE = 0x00020000 SF_APPEND = 0x00040000 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -15,6 +15,7 @@ import unittest import warnings +_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp') class PosixTester(unittest.TestCase): @@ -22,13 +23,15 @@ # create empty file fp = open(support.TESTFN, 'w+') fp.close() + self.teardown_files = [ support.TESTFN ] self._warnings_manager = support.check_warnings() self._warnings_manager.__enter__() warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) def tearDown(self): - support.unlink(support.TESTFN) + for teardown_file in self.teardown_files: + support.unlink(teardown_file) self._warnings_manager.__exit__(None, None, None) def testNoArgFunctions(self): @@ -268,7 +271,7 @@ def test_lchown(self): os.unlink(support.TESTFN) # create a symlink - os.symlink('/tmp/dummy-symlink-target', support.TESTFN) + os.symlink(_DUMMY_SYMLINK, support.TESTFN) self._test_all_chown_common(posix.lchown, support.TESTFN) def test_chdir(self): @@ -315,17 +318,49 @@ posix.utime(support.TESTFN, (int(now), int(now))) posix.utime(support.TESTFN, (now, now)) + def _test_chflags_regular_file(self, chflags_func, target_file): + st = os.stat(target_file) + self.assertTrue(hasattr(st, 'st_flags')) + chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE) + try: + new_st = os.stat(target_file) + self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags) + try: + fd = open(target_file, 'w+') + except IOError as e: + self.assertEqual(e.errno, errno.EPERM) + finally: + posix.chflags(target_file, st.st_flags) + + @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()') def test_chflags(self): - if hasattr(posix, 'chflags'): - st = os.stat(support.TESTFN) - if hasattr(st, 'st_flags'): - posix.chflags(support.TESTFN, st.st_flags) + self._test_chflags_regular_file(posix.chflags, support.TESTFN) - def test_lchflags(self): - if hasattr(posix, 'lchflags'): - st = os.stat(support.TESTFN) - if hasattr(st, 'st_flags'): - posix.lchflags(support.TESTFN, st.st_flags) + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_regular_file(self): + self._test_chflags_regular_file(posix.lchflags, support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_symlink(self): + testfn_st = os.stat(support.TESTFN) + + self.assertTrue(hasattr(testfn_st, 'st_flags')) + + os.symlink(support.TESTFN, _DUMMY_SYMLINK) + self.teardown_files.append(_DUMMY_SYMLINK) + dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + posix.lchflags(_DUMMY_SYMLINK, + dummy_symlink_st.st_flags | stat.UF_IMMUTABLE) + try: + new_testfn_st = os.stat(support.TESTFN) + new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags) + self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE, + new_dummy_symlink_st.st_flags) + finally: + posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags) def test_environ(self): if os.name == "nt": diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -181,6 +181,7 @@ Matt Conway David M. Cooke Jason R. Coombs +Garrett Cooper Greg Copeland Aldo Cortesi David Costanzo diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -99,6 +99,11 @@ Build ----- +- Issue #8746: Correct faulty configure checks so that os.chflags() and + os.lchflags() are once again built on systems that support these + functions (*BSD and OS X). Also add new stat file flags for OS X + (UF_HIDDEN and UF_COMPRESSED). + - Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, ensure "make install" creates symlinks in --prefix bin for the "-32" files in the framework bin directory like the installer does. @@ -106,6 +111,9 @@ Tests ----- +- Issue #8746: Add additional tests for os.chflags() and os.lchflags(). + Patch by Garrett Cooper. + - Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 on Mac OS X. (Patch by Ronald Oussoren) diff --git a/configure b/configure --- a/configure +++ b/configure @@ -9877,7 +9877,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -9886,7 +9886,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_chflags=yes @@ -9926,7 +9926,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -9935,7 +9935,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_lchflags=yes diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2689,7 +2689,7 @@ # On Tru64, chflags seems to be present, but calling it will # exit Python AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2698,7 +2698,7 @@ return 1; return 0; } -]]])], +]])], [ac_cv_have_chflags=yes], [ac_cv_have_chflags=no], [ac_cv_have_chflags=cross]) @@ -2707,11 +2707,11 @@ AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) fi if test "$ac_cv_have_chflags" = yes ; then - AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.]) + AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.]) fi AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2720,13 +2720,13 @@ return 1; return 0; } -]]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) +]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) ]) if test "$ac_cv_have_lchflags" = cross ; then AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) fi if test "$ac_cv_have_lchflags" = yes ; then - AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the `lchflags' function.]) + AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.]) fi dnl Check if system zlib has *Copy() functions diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -101,7 +101,7 @@ /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL -/* Define to 1 if you have the `chflags' function. */ +/* Define to 1 if you have the 'chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if you have the `chown' function. */ @@ -395,7 +395,7 @@ Solaris and Linux, the necessary defines are already defined.) */ #undef HAVE_LARGEFILE_SUPPORT -/* Define to 1 if you have the `lchflags' function. */ +/* Define to 1 if you have the 'lchflags' function. */ #undef HAVE_LCHFLAGS /* Define to 1 if you have the `lchmod' function. */ @@ -1152,6 +1152,9 @@ /* This must be defined on some systems to enable large file support. */ #undef _LARGEFILE_SOURCE +/* This must be defined on AIX systems to enable large file support. */ +#undef _LARGE_FILES + /* Define to 1 if on MINIX. */ #undef _MINIX -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:13:52 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:13:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=238746=3A_Correct_faulty_configure_checks_so_that_os?= =?utf8?q?=2Echflags=28=29_and?= Message-ID: http://hg.python.org/cpython/rev/9da64c0bdc33 changeset: 71032:9da64c0bdc33 parent: 71029:b7c61000ceec parent: 71031:529e26aa4fa3 user: Ned Deily date: Tue Jun 28 00:13:01 2011 -0700 summary: Issue #8746: Correct faulty configure checks so that os.chflags() and os.lchflags() are once again built on systems that support these functions (*BSD and OS X). Also add new stat file flags for OS X (UF_HIDDEN and UF_COMPRESSED). Also add additional tests for os.chflags() and os.lchflags(). (Tests by Garrett Cooper) files: Doc/library/os.rst | 2 + Doc/library/stat.rst | 12 +++++- Lib/stat.py | 2 + Lib/test/test_posix.py | 57 ++++++++++++++++++++++++----- Misc/ACKS | 1 + Misc/NEWS | 8 ++++ configure | 8 ++-- configure.in | 12 +++--- pyconfig.h.in | 4 +- 9 files changed, 81 insertions(+), 25 deletions(-) diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -1465,6 +1465,8 @@ * :data:`stat.UF_APPEND` * :data:`stat.UF_OPAQUE` * :data:`stat.UF_NOUNLINK` + * :data:`stat.UF_COMPRESSED` + * :data:`stat.UF_HIDDEN` * :data:`stat.SF_ARCHIVED` * :data:`stat.SF_IMMUTABLE` * :data:`stat.SF_APPEND` diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -307,13 +307,21 @@ The file may only be appended to. +.. data:: UF_OPAQUE + + The directory is opaque when viewed through a union stack. + .. data:: UF_NOUNLINK The file may not be renamed or deleted. -.. data:: UF_OPAQUE +.. data:: UF_COMPRESSED - The directory is opaque when viewed through a union stack. + The file is stored compressed (Mac OS X 10.6+). + +.. data:: UF_HIDDEN + + The file should not be displayed in a GUI (Mac OS X 10.5+). .. data:: SF_ARCHIVED diff --git a/Lib/stat.py b/Lib/stat.py --- a/Lib/stat.py +++ b/Lib/stat.py @@ -87,6 +87,8 @@ UF_APPEND = 0x00000004 UF_OPAQUE = 0x00000008 UF_NOUNLINK = 0x00000010 +UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed +UF_HIDDEN = 0x00008000 # OS X: file should not be displayed SF_ARCHIVED = 0x00010000 SF_IMMUTABLE = 0x00020000 SF_APPEND = 0x00040000 diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -16,6 +16,7 @@ import unittest import warnings +_DUMMY_SYMLINK = '%s/dummy-symlink' % os.getenv('TMPDIR', '/tmp') class PosixTester(unittest.TestCase): @@ -23,13 +24,15 @@ # create empty file fp = open(support.TESTFN, 'w+') fp.close() + self.teardown_files = [ support.TESTFN ] self._warnings_manager = support.check_warnings() self._warnings_manager.__enter__() warnings.filterwarnings('ignore', '.* potential security risk .*', RuntimeWarning) def tearDown(self): - support.unlink(support.TESTFN) + for teardown_file in self.teardown_files: + support.unlink(teardown_file) self._warnings_manager.__exit__(None, None, None) def testNoArgFunctions(self): @@ -426,7 +429,7 @@ def test_lchown(self): os.unlink(support.TESTFN) # create a symlink - os.symlink('/tmp/dummy-symlink-target', support.TESTFN) + os.symlink(_DUMMY_SYMLINK, support.TESTFN) self._test_all_chown_common(posix.lchown, support.TESTFN) def test_chdir(self): @@ -511,17 +514,49 @@ posix.utime(support.TESTFN, (int(now), int(now))) posix.utime(support.TESTFN, (now, now)) + def _test_chflags_regular_file(self, chflags_func, target_file): + st = os.stat(target_file) + self.assertTrue(hasattr(st, 'st_flags')) + chflags_func(target_file, st.st_flags | stat.UF_IMMUTABLE) + try: + new_st = os.stat(target_file) + self.assertEqual(st.st_flags | stat.UF_IMMUTABLE, new_st.st_flags) + try: + fd = open(target_file, 'w+') + except IOError as e: + self.assertEqual(e.errno, errno.EPERM) + finally: + posix.chflags(target_file, st.st_flags) + + @unittest.skipUnless(hasattr(posix, 'chflags'), 'test needs os.chflags()') def test_chflags(self): - if hasattr(posix, 'chflags'): - st = os.stat(support.TESTFN) - if hasattr(st, 'st_flags'): - posix.chflags(support.TESTFN, st.st_flags) + self._test_chflags_regular_file(posix.chflags, support.TESTFN) - def test_lchflags(self): - if hasattr(posix, 'lchflags'): - st = os.stat(support.TESTFN) - if hasattr(st, 'st_flags'): - posix.lchflags(support.TESTFN, st.st_flags) + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_regular_file(self): + self._test_chflags_regular_file(posix.lchflags, support.TESTFN) + + @unittest.skipUnless(hasattr(posix, 'lchflags'), 'test needs os.lchflags()') + def test_lchflags_symlink(self): + testfn_st = os.stat(support.TESTFN) + + self.assertTrue(hasattr(testfn_st, 'st_flags')) + + os.symlink(support.TESTFN, _DUMMY_SYMLINK) + self.teardown_files.append(_DUMMY_SYMLINK) + dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + posix.lchflags(_DUMMY_SYMLINK, + dummy_symlink_st.st_flags | stat.UF_IMMUTABLE) + try: + new_testfn_st = os.stat(support.TESTFN) + new_dummy_symlink_st = os.lstat(_DUMMY_SYMLINK) + + self.assertEqual(testfn_st.st_flags, new_testfn_st.st_flags) + self.assertEqual(dummy_symlink_st.st_flags | stat.UF_IMMUTABLE, + new_dummy_symlink_st.st_flags) + finally: + posix.lchflags(_DUMMY_SYMLINK, dummy_symlink_st.st_flags) def test_environ(self): if os.name == "nt": diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -191,6 +191,7 @@ Matt Conway David M. Cooke Jason R. Coombs +Garrett Cooper Greg Copeland Aldo Cortesi David Costanzo diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -857,6 +857,11 @@ Build ----- +- Issue #8746: Correct faulty configure checks so that os.chflags() and + os.lchflags() are once again built on systems that support these + functions (*BSD and OS X). Also add new stat file flags for OS X + (UF_HIDDEN and UF_COMPRESSED). + - Issue #10645: Installing Python does no longer create a Python-X.Y.Z-pyX.Y.egg-info file in the lib-dynload directory. @@ -908,6 +913,9 @@ Tests ----- +- Issue #8746: Add additional tests for os.chflags() and os.lchflags(). + Patch by Garrett Cooper. + - Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 2.8 + on Mac OS X. (Patch by Ronald Oussoren) diff --git a/configure b/configure --- a/configure +++ b/configure @@ -9912,7 +9912,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -9921,7 +9921,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_chflags=yes @@ -9961,7 +9961,7 @@ else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -[ + #include #include int main(int argc, char*argv[]) @@ -9970,7 +9970,7 @@ return 1; return 0; } -] + _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_lchflags=yes diff --git a/configure.in b/configure.in --- a/configure.in +++ b/configure.in @@ -2675,7 +2675,7 @@ # On Tru64, chflags seems to be present, but calling it will # exit Python AC_CACHE_CHECK([for chflags], [ac_cv_have_chflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2684,7 +2684,7 @@ return 1; return 0; } -]]])], +]])], [ac_cv_have_chflags=yes], [ac_cv_have_chflags=no], [ac_cv_have_chflags=cross]) @@ -2693,11 +2693,11 @@ AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) fi if test "$ac_cv_have_chflags" = yes ; then - AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the `chflags' function.]) + AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.]) fi AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[[ +AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main(int argc, char*argv[]) @@ -2706,13 +2706,13 @@ return 1; return 0; } -]]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) +]])],[ac_cv_have_lchflags=yes],[ac_cv_have_lchflags=no],[ac_cv_have_lchflags=cross]) ]) if test "$ac_cv_have_lchflags" = cross ; then AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) fi if test "$ac_cv_have_lchflags" = yes ; then - AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the `lchflags' function.]) + AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.]) fi dnl Check if system zlib has *Copy() functions diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -101,7 +101,7 @@ /* Define this if you have the type _Bool. */ #undef HAVE_C99_BOOL -/* Define to 1 if you have the `chflags' function. */ +/* Define to 1 if you have the 'chflags' function. */ #undef HAVE_CHFLAGS /* Define to 1 if you have the `chown' function. */ @@ -428,7 +428,7 @@ Solaris and Linux, the necessary defines are already defined.) */ #undef HAVE_LARGEFILE_SUPPORT -/* Define to 1 if you have the `lchflags' function. */ +/* Define to 1 if you have the 'lchflags' function. */ #undef HAVE_LCHFLAGS /* Define to 1 if you have the `lchmod' function. */ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:54:59 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:54:59 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyMTQx?= =?utf8?q?=3A_Install_a_copy_of_template_C_module_file_so_that?= Message-ID: http://hg.python.org/cpython/rev/c8ffa3891d5e changeset: 71033:c8ffa3891d5e branch: 2.7 parent: 71030:abfe28e7e5cd user: Ned Deily date: Tue Jun 28 00:39:19 2011 -0700 summary: Issue #12141: Install a copy of template C module file so that test_build_ext of test_distutils is no longer silently skipped when run outside of a build directory. files: Lib/distutils/tests/test_build_ext.py | 5 +++++ Makefile.pre.in | 6 +++++- Misc/NEWS | 4 ++++ 3 files changed, 14 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -19,6 +19,11 @@ ALREADY_TESTED = False def _get_source_filename(): + # use installed copy if available + tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c') + if os.path.exists(tests_f): + return tests_f + # otherwise try using copy from build directory srcdir = sysconfig.get_config_var('srcdir') if srcdir is None: return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c') diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -869,7 +869,7 @@ unittest unittest/test \ lib-old \ curses pydoc_data $(MACHDEPS) -libinstall: build_all $(srcdir)/Lib/$(PLATDIR) +libinstall: build_all $(srcdir)/Lib/$(PLATDIR) $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -925,6 +925,10 @@ done; \ done $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt + if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \ + $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ + $(DESTDIR)$(LIBDEST)/distutils/tests ; \ + fi PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi -tt $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -64,6 +64,10 @@ Tests ----- +- Issue #12141: Install a copy of template C module file so that + test_build_ext of test_distutils is no longer silently skipped when + run outside of a build directory. + - Issue #8746: Add additional tests for os.chflags() and os.lchflags(). Patch by Garrett Cooper. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:55:00 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:55:00 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyMTQx?= =?utf8?q?=3A_Install_a_copy_of_template_C_module_file_so_that?= Message-ID: http://hg.python.org/cpython/rev/de226a510b52 changeset: 71034:de226a510b52 branch: 3.2 parent: 71031:529e26aa4fa3 user: Ned Deily date: Tue Jun 28 00:42:50 2011 -0700 summary: Issue #12141: Install a copy of template C module file so that test_build_ext of test_distutils is no longer silently skipped when run outside of a build directory. files: Lib/distutils/tests/test_build_ext.py | 11 ++++++++++- Makefile.pre.in | 6 +++++- Misc/NEWS | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -22,6 +22,11 @@ ALREADY_TESTED = False def _get_source_filename(): + # use installed copy if available + tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c') + if os.path.exists(tests_f): + return tests_f + # otherwise try using copy from build directory srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') @@ -35,7 +40,9 @@ self.tmp_dir = self.mkdtemp() self.sys_path = sys.path, sys.path[:] sys.path.append(self.tmp_dir) - shutil.copy(_get_source_filename(), self.tmp_dir) + filename = _get_source_filename() + if os.path.exists(filename): + shutil.copy(filename, self.tmp_dir) if sys.version > "2.6": import site self.old_user_base = site.USER_BASE @@ -65,6 +72,8 @@ def test_build_ext(self): global ALREADY_TESTED xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') + if not os.path.exists(xx_c): + return xx_ext = Extension('xx', [xx_c]) dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) dist.package_dir = self.tmp_dir diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -928,7 +928,7 @@ multiprocessing multiprocessing/dummy \ unittest unittest/test \ curses pydoc_data $(MACHDEPS) -libinstall: build_all $(srcdir)/Lib/$(PLATDIR) +libinstall: build_all $(srcdir)/Lib/$(PLATDIR) $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -984,6 +984,10 @@ done; \ done $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt + if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \ + $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ + $(DESTDIR)$(LIBDEST)/distutils/tests ; \ + fi -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -111,6 +111,10 @@ Tests ----- +- Issue #12141: Install a copy of template C module file so that + test_build_ext of test_distutils is no longer silently skipped when + run outside of a build directory. + - Issue #8746: Add additional tests for os.chflags() and os.lchflags(). Patch by Garrett Cooper. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 09:55:00 2011 From: python-checkins at python.org (ned.deily) Date: Tue, 28 Jun 2011 09:55:00 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=2312141=3A_Install_copies_of_template_C_module_file_s?= =?utf8?q?o_that?= Message-ID: http://hg.python.org/cpython/rev/ef8e9e99de88 changeset: 71035:ef8e9e99de88 parent: 71032:9da64c0bdc33 parent: 71034:de226a510b52 user: Ned Deily date: Tue Jun 28 00:53:54 2011 -0700 summary: Issue #12141: Install copies of template C module file so that test_build_ext of test_distutils and test_command_build_ext of test_packaging are no longer silently skipped when run outside of a build directory. files: Lib/distutils/tests/test_build_ext.py | 5 +++++ Lib/packaging/tests/test_command_build_ext.py | 5 +++++ Makefile.pre.in | 10 +++++++++- Misc/NEWS | 5 +++++ 4 files changed, 24 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -22,6 +22,11 @@ ALREADY_TESTED = False def _get_source_filename(): + # use installed copy if available + tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c') + if os.path.exists(tests_f): + return tests_f + # otherwise try using copy from build directory srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -14,6 +14,11 @@ def _get_source_filename(): + # use installed copy if available + tests_f = os.path.join(os.path.dirname(__file__), 'xxmodule.c') + if os.path.exists(tests_f): + return tests_f + # otherwise try using copy from build directory srcdir = sysconfig.get_config_var('srcdir') return os.path.join(srcdir, 'Modules', 'xxmodule.c') diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -982,7 +982,7 @@ multiprocessing multiprocessing/dummy \ unittest unittest/test \ curses pydoc_data $(MACHDEPS) -libinstall: build_all $(srcdir)/Lib/$(PLATDIR) +libinstall: build_all $(srcdir)/Lib/$(PLATDIR) $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -1038,6 +1038,14 @@ done; \ done $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt + if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \ + $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ + $(DESTDIR)$(LIBDEST)/distutils/tests ; \ + fi + if test -d $(DESTDIR)$(LIBDEST)/packaging/tests; then \ + $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ + $(DESTDIR)$(LIBDEST)/packaging/tests ; \ + fi -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ ./$(BUILDPYTHON) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ -d $(LIBDEST) -f \ diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -913,6 +913,11 @@ Tests ----- +- Issue #12141: Install copies of template C module file so that + test_build_ext of test_distutils and test_command_build_ext of + test_packaging are no longer silently skipped when + run outside of a build directory. + - Issue #8746: Add additional tests for os.chflags() and os.lchflags(). Patch by Garrett Cooper. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 16:40:21 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 16:40:21 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_use_the_Include_in_srcdir?= Message-ID: http://hg.python.org/cpython/rev/f8f1d5691ae8 changeset: 71036:f8f1d5691ae8 user: Benjamin Peterson date: Tue Jun 28 09:26:39 2011 -0500 summary: use the Include in srcdir files: Makefile.pre.in | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -73,7 +73,7 @@ # Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to # be able to build extension modules using the directories specified in the # environment variables -PY_CPPFLAGS= -I. -IInclude $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) +PY_CPPFLAGS= -I. -I$(srcdir)/Include $(CONFIGURE_CPPFLAGS) $(CPPFLAGS) PY_LDFLAGS= $(CONFIGURE_LDFLAGS) $(LDFLAGS) NO_AS_NEEDED= @NO_AS_NEEDED@ LDLAST= @LDLAST@ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 17:25:03 2011 From: python-checkins at python.org (benjamin.peterson) Date: Tue, 28 Jun 2011 17:25:03 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_unused_imports_=28cl?= =?utf8?q?oses_=2312432=29?= Message-ID: http://hg.python.org/cpython/rev/8c17e898e0e8 changeset: 71037:8c17e898e0e8 user: Benjamin Peterson date: Tue Jun 28 10:25:04 2011 -0500 summary: remove unused imports (closes #12432) A patch from Vincent Legoll. files: Lib/binhex.py | 1 - Lib/cgitb.py | 1 - Lib/contextlib.py | 1 - Lib/glob.py | 1 + Lib/inspect.py | 1 - Lib/textwrap.py | 2 +- Lib/turtle.py | 1 - 7 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Lib/binhex.py b/Lib/binhex.py --- a/Lib/binhex.py +++ b/Lib/binhex.py @@ -23,7 +23,6 @@ # import io import os -import sys import struct import binascii diff --git a/Lib/cgitb.py b/Lib/cgitb.py --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -31,7 +31,6 @@ import time import tokenize import traceback -import types def reset(): """Return a string that resets the CGI and browser to a known state.""" diff --git a/Lib/contextlib.py b/Lib/contextlib.py --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -2,7 +2,6 @@ import sys from functools import wraps -from warnings import warn __all__ = ["contextmanager", "closing", "ContextDecorator"] diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -1,5 +1,6 @@ """Filename globbing utility.""" +import sys import os import re import fnmatch diff --git a/Lib/inspect.py b/Lib/inspect.py --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -33,7 +33,6 @@ import os import types import itertools -import string import re import imp import tokenize diff --git a/Lib/textwrap.py b/Lib/textwrap.py --- a/Lib/textwrap.py +++ b/Lib/textwrap.py @@ -7,7 +7,7 @@ __revision__ = "$Id$" -import string, re +import re __all__ = ['TextWrapper', 'wrap', 'fill', 'dedent'] diff --git a/Lib/turtle.py b/Lib/turtle.py --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -108,7 +108,6 @@ import types import math import time -import os import inspect from os.path import isfile, split, join -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Tue Jun 28 19:33:50 2011 From: python-checkins at python.org (guido.van.rossum) Date: Tue, 28 Jun 2011 19:33:50 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Minimal_changes?= =?utf8?q?_to_make_byext=2Epy_script_work_with_Python_3_syntax=2E?= Message-ID: http://hg.python.org/cpython/rev/b2d4e6fc4f19 changeset: 71038:b2d4e6fc4f19 branch: 2.7 parent: 71033:c8ffa3891d5e user: Guido van Rossum date: Tue Jun 28 10:33:38 2011 -0700 summary: Minimal changes to make byext.py script work with Python 3 syntax. files: Tools/scripts/byext.py | 23 ++++++++++------------- 1 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Tools/scripts/byext.py b/Tools/scripts/byext.py --- a/Tools/scripts/byext.py +++ b/Tools/scripts/byext.py @@ -23,12 +23,11 @@ def statdir(self, dir): self.addstats("", "dirs", 1) try: - names = os.listdir(dir) - except os.error, err: + names = sorted(os.listdir(dir)) + except os.error as err: sys.stderr.write("Can't list %s: %s\n" % (dir, err)) self.addstats("", "unlistable", 1) return - names.sort() for name in names: if name.startswith(".#"): continue # Skip CVS temp files @@ -53,14 +52,14 @@ self.addstats(ext, "files", 1) try: f = open(filename, "rb") - except IOError, err: + except IOError as err: sys.stderr.write("Can't open %s: %s\n" % (filename, err)) self.addstats(ext, "unopenable", 1) return data = f.read() f.close() self.addstats(ext, "bytes", len(data)) - if '\0' in data: + if b'\0' in data: self.addstats(ext, "binary", 1) return if not data: @@ -77,14 +76,12 @@ d[key] = d.get(key, 0) + n def report(self): - exts = self.stats.keys() - exts.sort() + exts = sorted(self.stats.keys()) # Get the column keys columns = {} for ext in exts: columns.update(self.stats[ext]) - cols = columns.keys() - cols.sort() + cols = sorted(columns.keys()) colwidth = {} colwidth["ext"] = max([len(ext) for ext in exts]) minwidth = 6 @@ -109,14 +106,14 @@ cols.insert(0, "ext") def printheader(): for col in cols: - print "%*s" % (colwidth[col], col), - print + print("%*s" % (colwidth[col], col), end=" ") + print() printheader() for ext in exts: for col in cols: value = self.stats[ext].get(col, "") - print "%*s" % (colwidth[col], value), - print + print("%*s" % (colwidth[col], value), end=" ") + print() printheader() # Another header at the bottom def main(): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:57:29 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:57:29 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E6=29=3A_update_profile_?= =?utf8?q?license_=28closes_=2312417=29?= Message-ID: http://hg.python.org/cpython/rev/02150e60636b changeset: 71039:02150e60636b branch: 2.6 parent: 70634:3c4d84403bcf user: Benjamin Peterson date: Mon Jun 27 09:14:34 2011 -0500 summary: update profile license (closes #12417) files: Lib/profile.py | 39 ++++++++++++++----------------------- Lib/pstats.py | 37 ++++++++++++----------------------- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -2,35 +2,26 @@ # # Class for profiling python code. rev 1.0 6/2/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum """Class for profiling Python code.""" -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -2,35 +2,24 @@ # Class for printing reports on profiled python code. rev 1.0 4/1/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement # -# see profile.doc and profile.py for more info. - -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at # -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. +# http://www.apache.org/licenses/LICENSE-2.0 # -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys import os -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:57:30 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:57:30 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=283=2E1=29=3A_update_profile_?= =?utf8?q?license_=28closes_=2312417=29?= Message-ID: http://hg.python.org/cpython/rev/633597815463 changeset: 71040:633597815463 branch: 3.1 parent: 70961:03c8de42c206 user: Benjamin Peterson date: Mon Jun 27 09:14:34 2011 -0500 summary: update profile license (closes #12417) files: Lib/profile.py | 39 +++++++++++++--------------------- Lib/pstats.py | 42 +++++++++++++++---------------------- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -2,35 +2,26 @@ # # Class for profiling python code. rev 1.0 6/2/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum """Class for profiling Python code.""" -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys diff --git a/Lib/pstats.py b/Lib/pstats.py --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -2,34 +2,26 @@ # Class for printing reports on profiled python code. rev 1.0 4/1/94 # +# Written by James Roskind # Based on prior profile module by Sjoerd Mullender... # which was hacked somewhat by: Guido van Rossum -# -# see profile.py for more info. -# Copyright 1994, by InfoSeek Corporation, all rights reserved. -# Written by James Roskind -# -# Permission to use, copy, modify, and distribute this Python software -# and its associated documentation for any purpose (subject to the -# restriction in the following sentence) without fee is hereby granted, -# provided that the above copyright notice appears in all copies, and -# that both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of InfoSeek not be used in -# advertising or publicity pertaining to distribution of the software -# without specific, written prior permission. This permission is -# explicitly restricted to the copying and modification of the software -# to remain in Python, compiled Python, or other languages (such as C) -# wherein the modified or derived code is exclusively imported into a -# Python module. -# -# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY -# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF -# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +"""Class for profiling Python code.""" + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. import sys -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:57:31 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:57:31 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4xIC0+IDMuMik6?= =?utf8?q?_merge_3=2E1?= Message-ID: http://hg.python.org/cpython/rev/ecf17d9b0212 changeset: 71041:ecf17d9b0212 branch: 3.2 parent: 71034:de226a510b52 parent: 71040:633597815463 user: Benjamin Peterson date: Tue Jun 28 21:49:40 2011 -0500 summary: merge 3.1 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:57:32 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:57:32 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/3734313853e8 changeset: 71042:3734313853e8 parent: 71037:8c17e898e0e8 parent: 71041:ecf17d9b0212 user: Benjamin Peterson date: Tue Jun 28 21:49:49 2011 -0500 summary: merge 3.2 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:57:33 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:57:33 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi42KTogZml4IHdz?= Message-ID: http://hg.python.org/cpython/rev/919ee0c6f323 changeset: 71043:919ee0c6f323 branch: 2.6 parent: 71039:02150e60636b user: Benjamin Peterson date: Tue Jun 28 21:57:21 2011 -0500 summary: fix ws files: Lib/profile.py | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/profile.py b/Lib/profile.py --- a/Lib/profile.py +++ b/Lib/profile.py @@ -10,13 +10,13 @@ # Copyright Disney Enterprises, Inc. All Rights Reserved. # Licensed to PSF under a Contributor Agreement -# +# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 04:58:51 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 04:58:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi42IC0+IDIuNyk6?= =?utf8?q?_merge_2=2E6?= Message-ID: http://hg.python.org/cpython/rev/e1cf94dd4045 changeset: 71044:e1cf94dd4045 branch: 2.7 parent: 71038:b2d4e6fc4f19 parent: 71043:919ee0c6f323 user: Benjamin Peterson date: Tue Jun 28 21:58:27 2011 -0500 summary: merge 2.6 files: -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Wed Jun 29 05:07:57 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 29 Jun 2011 05:07:57 +0200 Subject: [Python-checkins] Daily reference leaks (8c17e898e0e8): sum=300 Message-ID: results for 8c17e898e0e8 on branch "default" -------------------------------------------- test_packaging leaked [100, 100, 100] references, sum=300 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflogrhNJ5G', '-x'] From python-checkins at python.org Wed Jun 29 05:24:47 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:47 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Correct_and_expand_OS_X_deployment_target_tests_in_distutils?= Message-ID: http://hg.python.org/cpython/rev/29c670f0d7d5 changeset: 71045:29c670f0d7d5 branch: 2.7 parent: 71038:b2d4e6fc4f19 user: Ned Deily date: Tue Jun 28 19:39:10 2011 -0700 summary: Issue #9516: Correct and expand OS X deployment target tests in distutils test_build_ext. files: Lib/distutils/tests/test_build_ext.py | 49 +++++++++++--- 1 files changed, 38 insertions(+), 11 deletions(-) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -9,7 +9,8 @@ from distutils.command.build_ext import build_ext from distutils import sysconfig from distutils.tests import support -from distutils.errors import DistutilsSetupError, CompileError +from distutils.errors import (DistutilsSetupError, CompileError, + DistutilsPlatformError) import unittest from test import test_support @@ -437,18 +438,43 @@ self.assertEqual(ext_path, wanted) @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target(self): - self._try_compile_deployment_target() + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(DistutilsPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): orig_environ = os.environ os.environ = orig_environ.copy() self.addCleanup(setattr, os, 'environ', orig_environ) - os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1' - self._try_compile_deployment_target() + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - def _try_compile_deployment_target(self): deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') with open(deptarget_c, 'w') as fp: @@ -457,16 +483,17 @@ int dummy; - #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else #error "Unexpected target" - #endif + #endif - ''')) + ''' % operator)) + # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') target = tuple(map(int, target.split('.'))) target = '%02d%01d0' % target - deptarget_ext = Extension( 'deptarget', [deptarget_c], -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:48 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:48 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Change_distutils_to_no_longer_globally_attempt_to_check_and?= Message-ID: http://hg.python.org/cpython/rev/01434498e55e changeset: 71046:01434498e55e branch: 2.7 user: Ned Deily date: Tue Jun 28 19:40:39 2011 -0700 summary: Issue #9516: Change distutils to no longer globally attempt to check and set the MACOSX_DEPLOYMENT_TARGET env variable for the interpreter process on OS X. This could cause failures in non-distutils subprocesses and was unreliable since tests or user programs could modify the interpreter environment after distutils set it. Instead, have distutils set the the deployment target only in the environment of each build subprocess. Continue to use the previous algorithm for deriving the deployment target value: if MACOSX_DEPLOYMENT_TARGET is not set in the interpreter's env: use the interpreter build configure MACOSX_DEPLOYMENT_TARGET elif the MACOSX_DEPLOYMENT_TARGET env value >= configure value: use the env MACOSX_DEPLOYMENT_TARGET else: # env value less than interpreter build configure value raise exception This allows building extensions that can only run on newer versions of the OS than the version python was built for, for example with a python built for 10.3 or later and an extension that needs to be built for 10.5. files: Lib/distutils/spawn.py | 28 +++++++++++++++++++++++++- Lib/distutils/sysconfig.py | 15 ------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -96,17 +96,43 @@ raise DistutilsExecError, \ "command '%s' failed with exit status %d" % (cmd[0], rc) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError, e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -380,21 +380,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:49 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:49 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Update_Misc/NEWS=2E?= Message-ID: http://hg.python.org/cpython/rev/e9e1fb4e3752 changeset: 71047:e9e1fb4e3752 branch: 2.7 user: Ned Deily date: Tue Jun 28 19:52:59 2011 -0700 summary: Issue #9516: Update Misc/NEWS. files: Misc/NEWS | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -16,6 +16,17 @@ Library ------- +- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to + check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the + interpreter process. This could cause failures in non-Distutils subprocesses + and was unreliable since tests or user programs could modify the interpreter + environment after Distutils set it. Instead, have Distutils set the the + deployment target only in the environment of each build subprocess. It is + still possible to globally override the default by setting + MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be + greater or equal to the default value, the value with which the interpreter + was built. + - Issue #11802: The cache in filecmp now has a maximum size of 100 so that it won't grow without bound. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:49 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:49 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Correct_and_expand_OS_X_deployment_target_tests_in_distutils?= Message-ID: http://hg.python.org/cpython/rev/bb89023191a0 changeset: 71048:bb89023191a0 branch: 3.2 parent: 71034:de226a510b52 user: Ned Deily date: Tue Jun 28 19:43:15 2011 -0700 summary: Issue #9516: Correct and expand OS X deployment target tests in distutils test_build_ext. files: Lib/distutils/tests/test_build_ext.py | 47 +++++++++++--- 1 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -11,7 +11,8 @@ from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import ( - CompileError, DistutilsSetupError, UnknownFileError) + CompileError, DistutilsPlatformError, DistutilsSetupError, + UnknownFileError) import unittest from test import support @@ -431,18 +432,43 @@ @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target(self): - self._try_compile_deployment_target() + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(DistutilsPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): orig_environ = os.environ os.environ = orig_environ.copy() self.addCleanup(setattr, os, 'environ', orig_environ) - os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1' - self._try_compile_deployment_target() + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - def _try_compile_deployment_target(self): deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') with open(deptarget_c, 'w') as fp: @@ -451,16 +477,17 @@ int dummy; - #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else #error "Unexpected target" #endif - ''')) + ''' % operator)) + # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') target = tuple(map(int, target.split('.'))) target = '%02d%01d0' % target - deptarget_ext = Extension( 'deptarget', [deptarget_c], -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:50 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:50 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Change_distutils_to_no_longer_globally_attempt_to_check_and?= Message-ID: http://hg.python.org/cpython/rev/b95eee310931 changeset: 71049:b95eee310931 branch: 3.2 user: Ned Deily date: Tue Jun 28 19:44:24 2011 -0700 summary: Issue #9516: Change distutils to no longer globally attempt to check and set the MACOSX_DEPLOYMENT_TARGET env variable for the interpreter process on OS X. This could cause failures in non-distutils subprocesses and was unreliable since tests or user programs could modify the interpreter environment after distutils set it. Instead, have distutils set the the deployment target only in the environment of each build subprocess. Continue to use the previous algorithm for deriving the deployment target value: if MACOSX_DEPLOYMENT_TARGET is not set in the interpreter's env: use the interpreter build configure MACOSX_DEPLOYMENT_TARGET elif the MACOSX_DEPLOYMENT_TARGET env value >= configure value: use the env MACOSX_DEPLOYMENT_TARGET else: # env value less than interpreter build configure value raise exception This allows building extensions that can only run on newer versions of the OS than the version python was built for, for example with a python built for 10.3 or later and an extension that needs to be built for 10.5. files: Lib/distutils/spawn.py | 29 +++++++++++++++++++++++++- Lib/distutils/sysconfig.py | 15 ------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -96,15 +96,42 @@ raise DistutilsExecError( "command '%s' failed with exit status %d" % (cmd[0], rc)) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None + def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError as e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -419,21 +419,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif [int(x) for x in cfg_target.split('.')] > [int(x) for x in cur_target.split('.')]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:51 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:51 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzk1MTY6?= =?utf8?q?_Update_Misc/NEWS=2E?= Message-ID: http://hg.python.org/cpython/rev/8e0cfba9c8c4 changeset: 71050:8e0cfba9c8c4 branch: 3.2 user: Ned Deily date: Tue Jun 28 19:51:30 2011 -0700 summary: Issue #9516: Update Misc/NEWS. files: Misc/NEWS | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,17 @@ Library ------- +- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to + check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the + interpreter process. This could cause failures in non-Distutils subprocesses + and was unreliable since tests or user programs could modify the interpreter + environment after Distutils set it. Instead, have Distutils set the the + deployment target only in the environment of each build subprocess. It is + still possible to globally override the default by setting + MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be + greater or equal to the default value, the value with which the interpreter + was built. + - Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:51 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=239516=3A_Merge_Distutils_changes_from_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/371a818687a5 changeset: 71051:371a818687a5 parent: 71037:8c17e898e0e8 parent: 71050:8e0cfba9c8c4 user: Ned Deily date: Tue Jun 28 20:01:52 2011 -0700 summary: Issue #9516: Merge Distutils changes from 3.2 files: Lib/distutils/spawn.py | 29 ++++++++- Lib/distutils/sysconfig.py | 15 ---- Lib/distutils/tests/test_build_ext.py | 47 +++++++++++--- Misc/NEWS | 11 +++ 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -96,15 +96,42 @@ raise DistutilsExecError( "command '%s' failed with exit status %d" % (cmd[0], rc)) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None + def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError as e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -419,21 +419,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif [int(x) for x in cfg_target.split('.')] > [int(x) for x in cur_target.split('.')]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -11,7 +11,8 @@ from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import ( - CompileError, DistutilsSetupError, UnknownFileError) + CompileError, DistutilsPlatformError, DistutilsSetupError, + UnknownFileError) import unittest from test import support @@ -431,18 +432,43 @@ @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target(self): - self._try_compile_deployment_target() + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(DistutilsPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): orig_environ = os.environ os.environ = orig_environ.copy() self.addCleanup(setattr, os, 'environ', orig_environ) - os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1' - self._try_compile_deployment_target() + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - def _try_compile_deployment_target(self): deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') with open(deptarget_c, 'w') as fp: @@ -451,16 +477,17 @@ int dummy; - #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else #error "Unexpected target" #endif - ''')) + ''' % operator)) + # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') target = tuple(map(int, target.split('.'))) target = '%02d%01d0' % target - deptarget_ext = Extension( 'deptarget', [deptarget_c], diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,17 @@ Library ------- +- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to + check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the + interpreter process. This could cause failures in non-Distutils subprocesses + and was unreliable since tests or user programs could modify the interpreter + environment after Distutils set it. Instead, have Distutils set the the + deployment target only in the environment of each build subprocess. It is + still possible to globally override the default by setting + MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be + greater or equal to the default value, the value with which the interpreter + was built. + - Issue #12422: In the copy module, don't store objects that are their own copy in the memo dict. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:52 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=239516=3A_Port_OS_X_?= =?utf8?q?deployment_target_tests_from_distutils_to_packaging?= Message-ID: http://hg.python.org/cpython/rev/47b670d386cd changeset: 71052:47b670d386cd user: Ned Deily date: Tue Jun 28 20:03:17 2011 -0700 summary: Issue #9516: Port OS X deployment target tests from distutils to packaging test_command_build_ext. files: Lib/packaging/tests/test_command_build_ext.py | 93 +++++++++- 1 files changed, 92 insertions(+), 1 deletions(-) diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -3,9 +3,11 @@ import site import shutil import sysconfig +import textwrap from io import StringIO from packaging.dist import Distribution -from packaging.errors import UnknownFileError, CompileError +from packaging.errors import (UnknownFileError, CompileError, + PackagingPlatformError) from packaging.command.build_ext import build_ext from packaging.compiler.extension import Extension from test.script_helper import assert_python_ok @@ -362,6 +364,95 @@ wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) self.assertEqual(wanted, path) + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(PackagingPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): + orig_environ = os.environ + os.environ = orig_environ.copy() + self.addCleanup(setattr, os, 'environ', orig_environ) + + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target + + deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') + + with open(deptarget_c, 'w') as fp: + fp.write(textwrap.dedent('''\ + #include + + int dummy; + + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else + #error "Unexpected target" + #endif + + ''' % operator)) + + # get the deployment target that the interpreter was built with + target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + target = tuple(map(int, target.split('.'))) + target = '%02d%01d0' % target + + deptarget_ext = Extension( + 'deptarget', + [deptarget_c], + extra_compile_args=['-DTARGET=%s' % (target,)], + ) + dist = Distribution({ + 'name': 'deptarget', + 'ext_modules': [deptarget_ext], + }) + dist.package_dir = self.tmp_dir + cmd = build_ext(dist) + cmd.build_lib = self.tmp_dir + cmd.build_temp = self.tmp_dir + + try: + old_stdout = sys.stdout + if not verbose: + # silence compiler output + sys.stdout = StringIO() + try: + cmd.ensure_finalized() + cmd.run() + finally: + sys.stdout = old_stdout + + except CompileError: + self.fail("Wrong deployment target during compilation") + def test_suite(): src = _get_source_filename() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:53 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:53 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=239516=3A_Port_the_r?= =?utf8?q?evised_deployment_target_processing_for_OSX_from?= Message-ID: http://hg.python.org/cpython/rev/c1ae16fce76d changeset: 71053:c1ae16fce76d user: Ned Deily date: Tue Jun 28 20:04:24 2011 -0700 summary: Issue #9516: Port the revised deployment target processing for OSX from distutils to packaging. files: Lib/packaging/util.py | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -757,6 +757,9 @@ else: return path, '' +if sys.platform == 'darwin': + _cfg_target = None + _cfg_target_split = None def spawn(cmd, search_path=True, verbose=0, dry_run=False, env=None): """Run another program specified as a command list 'cmd' in a new process. @@ -781,6 +784,26 @@ if dry_run: logging.debug('dry run, no process actually spawned') return + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + env = env or os.environ + cur_target = env.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise PackagingPlatformError(my_msg) + env = dict(env, MACOSX_DEPLOYMENT_TARGET=cur_target) + exit_status = subprocess.call(cmd, env=env) if exit_status != 0: msg = "command %r failed with exit status %d" -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:53 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:53 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=239516=3A_Update_Mis?= =?utf8?q?c/NEWS_to_include_packaging=2E?= Message-ID: http://hg.python.org/cpython/rev/1bd45742751b changeset: 71054:1bd45742751b user: Ned Deily date: Tue Jun 28 20:08:34 2011 -0700 summary: Issue #9516: Update Misc/NEWS to include packaging. files: Misc/NEWS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -209,7 +209,7 @@ still possible to globally override the default by setting MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be greater or equal to the default value, the value with which the interpreter - was built. + was built. Also, implement the same handling in packaging. - Issue #12422: In the copy module, don't store objects that are their own copy in the memo dict. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:54 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:54 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf8?q?_Merge_2=2E7?= Message-ID: http://hg.python.org/cpython/rev/cdfcd00873cd changeset: 71055:cdfcd00873cd branch: 2.7 parent: 71047:e9e1fb4e3752 parent: 71044:e1cf94dd4045 user: Ned Deily date: Tue Jun 28 20:13:03 2011 -0700 summary: Merge 2.7 files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:54 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:54 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_Merge_default=2E?= Message-ID: http://hg.python.org/cpython/rev/6a3f98e9db79 changeset: 71056:6a3f98e9db79 parent: 71042:3734313853e8 parent: 71054:1bd45742751b user: Ned Deily date: Tue Jun 28 20:16:55 2011 -0700 summary: Merge default. files: Lib/distutils/spawn.py | 29 +++- Lib/distutils/sysconfig.py | 15 - Lib/distutils/tests/test_build_ext.py | 47 +++- Lib/packaging/tests/test_command_build_ext.py | 93 +++++++++- Lib/packaging/util.py | 23 ++ Misc/NEWS | 11 + 6 files changed, 191 insertions(+), 27 deletions(-) diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -96,15 +96,42 @@ raise DistutilsExecError( "command '%s' failed with exit status %d" % (cmd[0], rc)) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None + def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError as e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -419,21 +419,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif [int(x) for x in cfg_target.split('.')] > [int(x) for x in cur_target.split('.')]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -11,7 +11,8 @@ from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import ( - CompileError, DistutilsSetupError, UnknownFileError) + CompileError, DistutilsPlatformError, DistutilsSetupError, + UnknownFileError) import unittest from test import support @@ -431,18 +432,43 @@ @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target(self): - self._try_compile_deployment_target() + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(DistutilsPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): orig_environ = os.environ os.environ = orig_environ.copy() self.addCleanup(setattr, os, 'environ', orig_environ) - os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1' - self._try_compile_deployment_target() + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - def _try_compile_deployment_target(self): deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') with open(deptarget_c, 'w') as fp: @@ -451,16 +477,17 @@ int dummy; - #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else #error "Unexpected target" #endif - ''')) + ''' % operator)) + # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') target = tuple(map(int, target.split('.'))) target = '%02d%01d0' % target - deptarget_ext = Extension( 'deptarget', [deptarget_c], diff --git a/Lib/packaging/tests/test_command_build_ext.py b/Lib/packaging/tests/test_command_build_ext.py --- a/Lib/packaging/tests/test_command_build_ext.py +++ b/Lib/packaging/tests/test_command_build_ext.py @@ -3,9 +3,11 @@ import site import shutil import sysconfig +import textwrap from io import StringIO from packaging.dist import Distribution -from packaging.errors import UnknownFileError, CompileError +from packaging.errors import (UnknownFileError, CompileError, + PackagingPlatformError) from packaging.command.build_ext import build_ext from packaging.compiler.extension import Extension from test.script_helper import assert_python_ok @@ -362,6 +364,95 @@ wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) self.assertEqual(wanted, path) + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(PackagingPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', + 'test only relevant for Mac OS X') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): + orig_environ = os.environ + os.environ = orig_environ.copy() + self.addCleanup(setattr, os, 'environ', orig_environ) + + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target + + deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') + + with open(deptarget_c, 'w') as fp: + fp.write(textwrap.dedent('''\ + #include + + int dummy; + + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else + #error "Unexpected target" + #endif + + ''' % operator)) + + # get the deployment target that the interpreter was built with + target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + target = tuple(map(int, target.split('.'))) + target = '%02d%01d0' % target + + deptarget_ext = Extension( + 'deptarget', + [deptarget_c], + extra_compile_args=['-DTARGET=%s' % (target,)], + ) + dist = Distribution({ + 'name': 'deptarget', + 'ext_modules': [deptarget_ext], + }) + dist.package_dir = self.tmp_dir + cmd = build_ext(dist) + cmd.build_lib = self.tmp_dir + cmd.build_temp = self.tmp_dir + + try: + old_stdout = sys.stdout + if not verbose: + # silence compiler output + sys.stdout = StringIO() + try: + cmd.ensure_finalized() + cmd.run() + finally: + sys.stdout = old_stdout + + except CompileError: + self.fail("Wrong deployment target during compilation") + def test_suite(): src = _get_source_filename() diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py --- a/Lib/packaging/util.py +++ b/Lib/packaging/util.py @@ -757,6 +757,9 @@ else: return path, '' +if sys.platform == 'darwin': + _cfg_target = None + _cfg_target_split = None def spawn(cmd, search_path=True, verbose=0, dry_run=False, env=None): """Run another program specified as a command list 'cmd' in a new process. @@ -781,6 +784,26 @@ if dry_run: logging.debug('dry run, no process actually spawned') return + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + env = env or os.environ + cur_target = env.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise PackagingPlatformError(my_msg) + env = dict(env, MACOSX_DEPLOYMENT_TARGET=cur_target) + exit_status = subprocess.call(cmd, env=env) if exit_status != 0: msg = "command %r failed with exit status %d" diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,17 @@ Library ------- +- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to + check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the + interpreter process. This could cause failures in non-Distutils subprocesses + and was unreliable since tests or user programs could modify the interpreter + environment after Distutils set it. Instead, have Distutils set the the + deployment target only in the environment of each build subprocess. It is + still possible to globally override the default by setting + MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be + greater or equal to the default value, the value with which the interpreter + was built. Also, implement the same handling in packaging. + - Issue #12422: In the copy module, don't store objects that are their own copy in the memo dict. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:55 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:55 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAobWVyZ2UgMy4yIC0+IDMuMik6?= =?utf8?q?_Merge_3=2E2?= Message-ID: http://hg.python.org/cpython/rev/69e26e98bdd4 changeset: 71057:69e26e98bdd4 branch: 3.2 parent: 71041:ecf17d9b0212 parent: 71050:8e0cfba9c8c4 user: Ned Deily date: Tue Jun 28 20:19:36 2011 -0700 summary: Merge 3.2 files: Lib/distutils/spawn.py | 29 ++++++++- Lib/distutils/sysconfig.py | 15 ---- Lib/distutils/tests/test_build_ext.py | 47 +++++++++++--- Misc/NEWS | 11 +++ 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -96,15 +96,42 @@ raise DistutilsExecError( "command '%s' failed with exit status %d" % (cmd[0], rc)) +if sys.platform == 'darwin': + from distutils import sysconfig + _cfg_target = None + _cfg_target_split = None + def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return exec_fn = search_path and os.execvp or os.execv + exec_args = [cmd[0], cmd] + if sys.platform == 'darwin': + global _cfg_target, _cfg_target_split + if _cfg_target is None: + _cfg_target = sysconfig.get_config_var( + 'MACOSX_DEPLOYMENT_TARGET') or '' + if _cfg_target: + _cfg_target_split = [int(x) for x in _cfg_target.split('.')] + if _cfg_target: + # ensure that the deployment target of build process is not less + # than that used when the interpreter was built. This ensures + # extension modules are built with correct compatibility values + cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) + if _cfg_target_split > [int(x) for x in cur_target.split('.')]: + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' + 'now "%s" but "%s" during configure' + % (cur_target, _cfg_target)) + raise DistutilsPlatformError(my_msg) + env = dict(os.environ, + MACOSX_DEPLOYMENT_TARGET=cur_target) + exec_fn = search_path and os.execvpe or os.execve + exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(cmd[0], cmd) + exec_fn(*exec_args) except OSError as e: sys.stderr.write("unable to execute %s: %s\n" % (cmd[0], e.strerror)) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -419,21 +419,6 @@ raise DistutilsPlatformError(my_msg) - # On MacOSX we need to check the setting of the environment variable - # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so - # it needs to be compatible. - # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: - cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] - cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') - if cur_target == '': - cur_target = cfg_target - os.environ['MACOSX_DEPLOYMENT_TARGET'] = cfg_target - elif [int(x) for x in cfg_target.split('.')] > [int(x) for x in cur_target.split('.')]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' - % (cur_target, cfg_target)) - raise DistutilsPlatformError(my_msg) - # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -11,7 +11,8 @@ from distutils.tests.support import LoggingSilencer from distutils.extension import Extension from distutils.errors import ( - CompileError, DistutilsSetupError, UnknownFileError) + CompileError, DistutilsPlatformError, DistutilsSetupError, + UnknownFileError) import unittest from test import support @@ -431,18 +432,43 @@ @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target(self): - self._try_compile_deployment_target() + def test_deployment_target_default(self): + # Issue 9516: Test that, in the absence of the environment variable, + # an extension module is compiled with the same deployment target as + # the interpreter. + self._try_compile_deployment_target('==', None) + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_too_low(self): + # Issue 9516: Test that an extension module is not allowed to be + # compiled with a deployment target less than that of the interpreter. + self.assertRaises(DistutilsPlatformError, + self._try_compile_deployment_target, '>', '10.1') + + @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') + def test_deployment_target_higher_ok(self): + # Issue 9516: Test that an extension module can be compiled with a + # deployment target higher than that of the interpreter: the ext + # module may depend on some newer OS feature. + deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') + if deptarget: + # increment the minor version number (i.e. 10.6 -> 10.7) + deptarget = [int(x) for x in deptarget.split('.')] + deptarget[-1] += 1 + deptarget = '.'.join(str(i) for i in deptarget) + self._try_compile_deployment_target('<', deptarget) + + def _try_compile_deployment_target(self, operator, target): orig_environ = os.environ os.environ = orig_environ.copy() self.addCleanup(setattr, os, 'environ', orig_environ) - os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1' - self._try_compile_deployment_target() + if target is None: + if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): + del os.environ['MACOSX_DEPLOYMENT_TARGET'] + else: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - def _try_compile_deployment_target(self): deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') with open(deptarget_c, 'w') as fp: @@ -451,16 +477,17 @@ int dummy; - #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED + #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED + #else #error "Unexpected target" #endif - ''')) + ''' % operator)) + # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') target = tuple(map(int, target.split('.'))) target = '%02d%01d0' % target - deptarget_ext = Extension( 'deptarget', [deptarget_c], diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,17 @@ Library ------- +- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to + check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the + interpreter process. This could cause failures in non-Distutils subprocesses + and was unreliable since tests or user programs could modify the interpreter + environment after Distutils set it. Instead, have Distutils set the the + deployment target only in the environment of each build subprocess. It is + still possible to globally override the default by setting + MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be + greater or equal to the default value, the value with which the interpreter + was built. + - Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira Kitada. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 05:24:56 2011 From: python-checkins at python.org (ned.deily) Date: Wed, 29 Jun 2011 05:24:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Merge_3=2E2_to_default?= Message-ID: http://hg.python.org/cpython/rev/5fff46383e9d changeset: 71058:5fff46383e9d parent: 71056:6a3f98e9db79 parent: 71057:69e26e98bdd4 user: Ned Deily date: Tue Jun 28 20:22:30 2011 -0700 summary: Merge 3.2 to default files: -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 06:23:29 2011 From: python-checkins at python.org (brett.cannon) Date: Wed, 29 Jun 2011 06:23:29 +0200 (CEST) Subject: [Python-checkins] r88860 - sandbox/trunk/pep362/pep362.py Message-ID: <3R3rTs05yhzMFM@mail.python.org> Author: brett.cannon Date: Wed Jun 29 06:23:28 2011 New Revision: 88860 Log: Fix a spelling mistake in a docstring. Modified: sandbox/trunk/pep362/pep362.py Modified: sandbox/trunk/pep362/pep362.py ============================================================================== --- sandbox/trunk/pep362/pep362.py (original) +++ sandbox/trunk/pep362/pep362.py Wed Jun 29 06:23:28 2011 @@ -59,7 +59,7 @@ * var_args Name of the variable positional parameter, else ''. * var_kw_wargs - Name of the variable keywrod parameter, else ''. + Name of the variable keyword parameter, else ''. * var_annotations Dict keyed on the variable parameter names with the values of the annotation for the parameter. If an annotation does not exist for a From python-checkins at python.org Wed Jun 29 10:43:52 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 10:43:52 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312303=3A_run_sig*w?= =?utf8?q?ait*=28=29_tests_in_a_subprocesss?= Message-ID: http://hg.python.org/cpython/rev/00ca0c2c7bc0 changeset: 71059:00ca0c2c7bc0 user: Victor Stinner date: Wed Jun 29 10:43:02 2011 +0200 summary: Issue #12303: run sig*wait*() tests in a subprocesss ... instead of using fork(): sig*wait*() functions behave differently (not correctly) after a fork, especially on FreeBSD 6. Skip also test_sigtimedwait_poll() on FreeBSD 6 because of a kernel bug. files: Lib/test/test_signal.py | 139 ++++++++++++++++----------- 1 files changed, 82 insertions(+), 57 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -520,7 +520,6 @@ functions. """ def setUp(self): - self.hndl_called = False self.has_pthread_kill = hasattr(signal, 'pthread_kill') def handler(self, signum, frame): @@ -610,87 +609,108 @@ @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), 'need signal.pthread_sigmask()') - @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork()') - def wait_helper(self, test, handler, blocked): - signum = signal.SIGALRM + def wait_helper(self, test, blocked): + """ + test: body of the "def test(signum):" function. + blocked: number of the blocked signal + """ + code = ''' +import signal +import sys + +def handler(signum, frame): + 1/0 + +def test(signum): +%s + +blocked = %s +signum = signal.SIGALRM + +# child: block and wait the signal +try: + signal.signal(signum, handler) + signal.pthread_sigmask(signal.SIG_BLOCK, [blocked]) + + # Do the tests + test(signum) + + # The handler must not be called on unblock + try: + signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked]) + except ZeroDivisionError: + print("the signal handler has been called", + file=sys.stderr) + sys.exit(1) +except BaseException as err: + print("error: {}".format(err), file=sys.stderr) + sys.stderr.flush() + sys.exit(1) +''' % (test, blocked) # sig*wait* must be called with the signal blocked: since the current - # process might have several threads running, we fork() a child process - # to have a single thread. - pid = os.fork() - if pid == 0: - # child: block and wait the signal - try: - signal.signal(signum, handler) - signal.pthread_sigmask(signal.SIG_BLOCK, [blocked]) - - # Do the tests - test(signum) - - # The handler must not be called on unblock - try: - signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked]) - except ZeroDivisionError: - print("the signal handler has been called", - file=sys.stderr) - os._exit(1) - except BaseException as err: - print("error: {}".format(err), file=sys.stderr) - sys.stderr.flush() - os._exit(1) - else: - os._exit(0) - else: - # parent: check that the child correcty received the signal - self.assertEqual(os.waitpid(pid, 0), (pid, 0)) + # process might have several threads running, use a subprocess to have + # a single thread. + assert_python_ok('-c', code) @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') def test_sigwait(self): - def test(signum): + test = ''' signal.alarm(1) - self.assertEqual(signum, signal.sigwait([signum])) + received = signal.sigwait([signum]) + assert received == signum , 'received %s, not %s' % (received, signum) + ''' - self.wait_helper(test, self.handler, signal.SIGALRM) + self.wait_helper(test, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), 'need signal.sigwaitinfo()') def test_sigwaitinfo(self): - def test(signum): + test = ''' signal.alarm(1) info = signal.sigwaitinfo([signum]) - self.assertEqual(signum, info.si_signo) + assert info.si_signo == signum, "info.si_signo != %s" % signum + ''' - self.wait_helper(test, self.handler, signal.SIGALRM) + self.wait_helper(test, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') def test_sigtimedwait(self): - def test(signum): + test = ''' signal.alarm(1) info = signal.sigtimedwait([signum], (10, 1000)) - self.assertEqual(signum, info.si_signo) + assert info.si_signo == signum, 'info.si_signo != %s' % signum + ''' - self.wait_helper(test, self.handler, signal.SIGALRM) + self.wait_helper(test, signal.SIGALRM) - # check that polling with sigtimedwait works @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') + # issue #12303: sigtimedwait() takes 30 seconds on FreeBSD 6 (kernel bug) + @unittest.skipIf(sys.platform =='freebsd6', + 'sigtimedwait() with a null timeout doens\'t work on FreeBSD 6') def test_sigtimedwait_poll(self): - def test(signum): - self.kill(signum) + # check that polling with sigtimedwait works + test = ''' + import os + os.kill(os.getpid(), signum) info = signal.sigtimedwait([signum], (0, 0)) - self.assertEqual(signum, info.si_signo) + assert info.si_signo == signum, 'info.si_signo != %s' % signum + ''' - self.wait_helper(test, self.handler, signal.SIGALRM) + self.wait_helper(test, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') def test_sigtimedwait_timeout(self): - def test(signum): - self.assertEqual(None, signal.sigtimedwait([signum], (1, 35500))) + test = ''' + received = signal.sigtimedwait([signum], (1, 0)) + assert received is None, "received=%r" % (received,) + ''' - self.wait_helper(test, self.handler, signal.SIGALRM) + self.wait_helper(test, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), 'need signal.sigtimedwait()') @@ -700,25 +720,30 @@ self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1)) self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0)) - def alarm_handler(self, signum, frame): - self.hndl_called = True - @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), 'need signal.sigwaitinfo()') def test_sigwaitinfo_interrupted(self): - def test(signum): + test = ''' + import errno + + hndl_called = True + def alarm_handler(signum, frame): + hndl_called = False + + signal.signal(signal.SIGALRM, alarm_handler) signal.alarm(1) try: signal.sigwaitinfo([signal.SIGUSR1]) except OSError as e: if e.errno == errno.EINTR: - self.assertTrue(self.hndl_called) + assert hndl_called, "SIGALRM handler not called" else: - self.fail("Expected EINTR to be raised by sigwaitinfo") + raise Exception("Expected EINTR to be raised by sigwaitinfo") else: - self.fail("Expected EINTR to be raised by sigwaitinfo") + raise Exception("Expected EINTR to be raised by sigwaitinfo") + ''' - self.wait_helper(test, self.alarm_handler, signal.SIGUSR1) + self.wait_helper(test, signal.SIGUSR1) @unittest.skipUnless(hasattr(signal, 'sigwait'), 'need signal.sigwait()') -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:04:23 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:04:23 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_regrtest_-W_doesn=27t_rerun_the_tests_twice_anymore=2C_but_c?= =?utf8?q?aptures?= Message-ID: http://hg.python.org/cpython/rev/949e0c0f5a38 changeset: 71060:949e0c0f5a38 branch: 3.2 parent: 71057:69e26e98bdd4 user: Victor Stinner date: Wed Jun 29 13:00:54 2011 +0200 summary: Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures the output and displays it on failure instead. regrtest -v doesn't print the error twice anymore if there is only one error. files: Lib/test/regrtest.py | 36 ++++++++++++++++++++++--------- Misc/NEWS | 4 +++ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -25,7 +25,7 @@ -v/--verbose -- run tests in verbose mode with output to stdout -w/--verbose2 -- re-run failed tests in verbose mode --W/--verbose3 -- re-run failed tests in verbose mode immediately +-W/--verbose3 -- display test output on failure -d/--debug -- print traceback for failed tests -q/--quiet -- no output unless one or more tests fail -S/--slow -- print the slowest 10 tests @@ -781,17 +781,27 @@ PASSED test passed """ - support.verbose = verbose # Tell tests to be moderately quiet if use_resources is not None: support.use_resources = use_resources try: - result = runtest_inner(test, verbose, quiet, huntrleaks, debug) - if result[0] == FAILED and rerun_failed: - cleanup_test_droppings(test, verbose) - sys.stdout.flush() - sys.stderr.flush() - print("Re-running test {} in verbose mode".format(test)) - runtest(test, True, quiet, huntrleaks, debug) + if rerun_failed: + support.verbose = True + orig_stderr = sys.stderr + with support.captured_stdout() as stream: + try: + sys.stderr = stream + result = runtest_inner(test, verbose, quiet, huntrleaks, + debug, display_failure=False) + if result[0] == FAILED: + output = stream.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stderr = orig_stderr + else: + support.verbose = verbose # Tell tests to be moderately quiet + result = runtest_inner(test, verbose, quiet, huntrleaks, debug, + display_failure=not verbose) return result finally: cleanup_test_droppings(test, verbose) @@ -960,7 +970,8 @@ return False -def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False): +def runtest_inner(test, verbose, quiet, + huntrleaks=False, debug=False, display_failure=True): support.unload(test) if verbose: capture_stdout = None @@ -1002,7 +1013,10 @@ except KeyboardInterrupt: raise except support.TestFailed as msg: - print("test", test, "failed --", msg, file=sys.stderr) + if display_failure: + print("test", test, "failed --", msg, file=sys.stderr) + else: + print("test", test, "failed", file=sys.stderr) sys.stderr.flush() return FAILED, test_time except: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -122,6 +122,10 @@ Tests ----- +- Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures + the output and displays it on failure instead. regrtest -v doesn't print the + error twice anymore if there is only one error. + - Issue #12141: Install a copy of template C module file so that test_build_ext of test_distutils is no longer silently skipped when run outside of a build directory. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:04:23 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:04:23 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_regrtest_-W_doesn=27t_re?= =?utf8?q?run_the_tests_twice_anymore=2C?= Message-ID: http://hg.python.org/cpython/rev/0172d40fdcd4 changeset: 71061:0172d40fdcd4 parent: 71059:00ca0c2c7bc0 parent: 71060:949e0c0f5a38 user: Victor Stinner date: Wed Jun 29 13:04:35 2011 +0200 summary: (merge 3.2) Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures the output and displays it on failure instead. regrtest -v doesn't print the error twice anymore if there is only one error. files: Lib/test/regrtest.py | 36 ++++++++++++++++++++++--------- Lib/test/test_os.py | 1 + Misc/NEWS | 4 +++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -30,7 +30,7 @@ -v/--verbose -- run tests in verbose mode with output to stdout -w/--verbose2 -- re-run failed tests in verbose mode --W/--verbose3 -- re-run failed tests in verbose mode immediately +-W/--verbose3 -- display test output on failure -d/--debug -- print traceback for failed tests -q/--quiet -- no output unless one or more tests fail -S/--slow -- print the slowest 10 tests @@ -831,20 +831,30 @@ PASSED test passed """ - support.verbose = verbose # Tell tests to be moderately quiet if use_resources is not None: support.use_resources = use_resources use_timeout = (timeout is not None) if use_timeout: faulthandler.dump_tracebacks_later(timeout, exit=True) try: - result = runtest_inner(test, verbose, quiet, huntrleaks, debug) - if result[0] == FAILED and rerun_failed: - cleanup_test_droppings(test, verbose) - sys.stdout.flush() - sys.stderr.flush() - print("Re-running test {} in verbose mode".format(test)) - runtest(test, True, quiet, huntrleaks, debug, timeout=timeout) + if rerun_failed: + support.verbose = True + orig_stderr = sys.stderr + with support.captured_stdout() as stream: + try: + sys.stderr = stream + result = runtest_inner(test, verbose, quiet, huntrleaks, + debug, display_failure=False) + if result[0] == FAILED: + output = stream.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stderr = orig_stderr + else: + support.verbose = verbose # Tell tests to be moderately quiet + result = runtest_inner(test, verbose, quiet, huntrleaks, debug, + display_failure=not verbose) return result finally: if use_timeout: @@ -1020,7 +1030,8 @@ return False -def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False): +def runtest_inner(test, verbose, quiet, + huntrleaks=False, debug=False, display_failure=True): support.unload(test) test_time = 0.0 @@ -1058,7 +1069,10 @@ except KeyboardInterrupt: raise except support.TestFailed as msg: - print("test", test, "failed --", msg, file=sys.stderr) + if display_failure: + print("test", test, "failed --", msg, file=sys.stderr) + else: + print("test", test, "failed", file=sys.stderr) sys.stderr.flush() return FAILED, test_time except: diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -40,6 +40,7 @@ tearDown = setUp def test_access(self): + self.assertEqual(1,2) f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) os.close(f) self.assertTrue(os.access(support.TESTFN, os.W_OK)) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -924,6 +924,10 @@ Tests ----- +- Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures + the output and displays it on failure instead. regrtest -v doesn't print the + error twice anymore if there is only one error. + - Issue #12141: Install copies of template C module file so that test_build_ext of test_distutils and test_command_build_ext of test_packaging are no longer silently skipped when -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:23:38 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:23:38 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312400=3A_oops=2C_r?= =?utf8?q?emove_debug_code=2E=2E=2E?= Message-ID: http://hg.python.org/cpython/rev/af799df478c6 changeset: 71062:af799df478c6 user: Victor Stinner date: Wed Jun 29 13:23:49 2011 +0200 summary: Issue #12400: oops, remove debug code... files: Lib/test/test_os.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -40,7 +40,6 @@ tearDown = setUp def test_access(self): - self.assertEqual(1,2) f = os.open(support.TESTFN, os.O_CREAT|os.O_RDWR) os.close(f) self.assertTrue(os.access(support.TESTFN, os.W_OK)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:24:54 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:24:54 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_remove_unused_variable?= Message-ID: http://hg.python.org/cpython/rev/69e102bfed2b changeset: 71063:69e102bfed2b branch: 3.2 parent: 71060:949e0c0f5a38 user: Victor Stinner date: Wed Jun 29 13:24:28 2011 +0200 summary: Issue #12400: remove unused variable files: Lib/test/regrtest.py | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -159,7 +159,6 @@ import os import random import re -import io import sys import time import errno @@ -973,10 +972,6 @@ def runtest_inner(test, verbose, quiet, huntrleaks=False, debug=False, display_failure=True): support.unload(test) - if verbose: - capture_stdout = None - else: - capture_stdout = io.StringIO() test_time = 0.0 refleak = False # True if the test leaked references. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:24:56 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:24:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_remove_unused_import?= Message-ID: http://hg.python.org/cpython/rev/9d53612333c7 changeset: 71064:9d53612333c7 parent: 71062:af799df478c6 parent: 71063:69e102bfed2b user: Victor Stinner date: Wed Jun 29 13:24:58 2011 +0200 summary: (merge 3.2) Issue #12400: remove unused import files: Lib/test/regrtest.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -168,7 +168,6 @@ import os import random import re -import io import sys import time import errno -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 13:43:48 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 13:43:48 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312400=3A_fix_test?= =?utf8?q?=5Ffaulthandler_if_regrtest_captures_sys=2Estderr?= Message-ID: http://hg.python.org/cpython/rev/80c7d63325f6 changeset: 71065:80c7d63325f6 user: Victor Stinner date: Wed Jun 29 13:44:05 2011 +0200 summary: Issue #12400: fix test_faulthandler if regrtest captures sys.stderr faulthandler.enable() requires that sys.stderr has a fileno() method. files: Lib/test/test_faulthandler.py | 32 ++++++++++++++++------ 1 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -1,6 +1,7 @@ from contextlib import contextmanager import datetime import faulthandler +import os import re import signal import subprocess @@ -230,17 +231,30 @@ self.assertNotEqual(exitcode, 0) def test_is_enabled(self): - was_enabled = faulthandler.is_enabled() + null_stderr = None + orig_stderr = sys.stderr try: - faulthandler.enable() - self.assertTrue(faulthandler.is_enabled()) - faulthandler.disable() - self.assertFalse(faulthandler.is_enabled()) + # regrtest may replace sys.stderr by io.StringIO object, but + # faulthandler.enable() requires that sys.stderr has a fileno() + # method + null_stderr = open(os.devnull, 'w') + sys.stderr = null_stderr + + was_enabled = faulthandler.is_enabled() + try: + faulthandler.enable() + self.assertTrue(faulthandler.is_enabled()) + faulthandler.disable() + self.assertFalse(faulthandler.is_enabled()) + finally: + if was_enabled: + faulthandler.enable() + else: + faulthandler.disable() finally: - if was_enabled: - faulthandler.enable() - else: - faulthandler.disable() + sys.stderr = orig_stderr + if null_stderr is not None: + null_stderr.close() def check_dump_traceback(self, filename): """ -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Wed Jun 29 14:37:00 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Wed, 29 Jun 2011 22:37:00 +1000 Subject: [Python-checkins] cpython: Issue #12400: fix test_faulthandler if regrtest captures sys.stderr In-Reply-To: References: Message-ID: On Wed, Jun 29, 2011 at 9:43 PM, victor.stinner wrote: > http://hg.python.org/cpython/rev/80c7d63325f6 > changeset: ? 71065:80c7d63325f6 > user: ? ? ? ?Victor Stinner > date: ? ? ? ?Wed Jun 29 13:44:05 2011 +0200 > summary: > ?Issue #12400: fix test_faulthandler if regrtest captures sys.stderr > > faulthandler.enable() requires that sys.stderr has a fileno() method. Would there be any value in falling back to sys.__stderr__ in the case where sys.stderr has been redirected? Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Wed Jun 29 14:59:37 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 14:59:37 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_don=27t_use_sys=2Estderr_in_test=5Fkqueue_because_it_may_be_?= =?utf8?q?replaced_by?= Message-ID: http://hg.python.org/cpython/rev/74c6afbb524a changeset: 71066:74c6afbb524a branch: 3.2 parent: 71063:69e102bfed2b user: Victor Stinner date: Wed Jun 29 14:59:10 2011 +0200 summary: Issue #12400: don't use sys.stderr in test_kqueue because it may be replaced by a io.StringIO object by regrtest (which has no file descriptor). files: Lib/test/test_kqueue.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -23,7 +23,10 @@ def test_create_event(self): from operator import lt, le, gt, ge - fd = sys.stderr.fileno() + + fd = os.open(os.devnull, os.O_WRONLY) + self.addCleanup(os.close, fd) + ev = select.kevent(fd) other = select.kevent(1000) self.assertEqual(ev.ident, fd) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 14:59:37 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 14:59:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_don=27t_use_sys=2Estderr?= =?utf8?q?_in_test=5Fkqueue_because_it_may_be?= Message-ID: http://hg.python.org/cpython/rev/c0afc8d00c0a changeset: 71067:c0afc8d00c0a parent: 71065:80c7d63325f6 parent: 71066:74c6afbb524a user: Victor Stinner date: Wed Jun 29 14:59:46 2011 +0200 summary: (merge 3.2) Issue #12400: don't use sys.stderr in test_kqueue because it may be replaced by a io.StringIO object by regrtest (which has no file descriptor). files: Lib/test/test_kqueue.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -23,7 +23,10 @@ def test_create_event(self): from operator import lt, le, gt, ge - fd = sys.stderr.fileno() + + fd = os.open(os.devnull, os.O_WRONLY) + self.addCleanup(os.close, fd) + ev = select.kevent(fd) other = select.kevent(1000) self.assertEqual(ev.ident, fd) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:26:01 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:26:01 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_runtest=28=29_reuses_the_same_io=2EStringIO_instance_for_all?= =?utf8?q?_calls?= Message-ID: http://hg.python.org/cpython/rev/6c54c334ea7a changeset: 71068:6c54c334ea7a branch: 3.2 parent: 71066:74c6afbb524a user: Victor Stinner date: Wed Jun 29 15:22:26 2011 +0200 summary: Issue #12400: runtest() reuses the same io.StringIO instance for all calls * Don't force verbose to True with option -W * Rename rerun_failed variable to output_on_failure files: Lib/test/regrtest.py | 57 ++++++++++++++++++------------- 1 files changed, 33 insertions(+), 24 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -154,22 +154,23 @@ """ import builtins +import errno import getopt +import io import json +import logging import os +import platform import random import re import sys +import sysconfig +import tempfile import time -import errno import traceback +import unittest import warnings -import unittest from inspect import isabstract -import tempfile -import platform -import sysconfig -import logging # Some times __path__ and __file__ are not absolute (e.g. while running from @@ -535,7 +536,7 @@ args_tuple = ( (test, verbose, quiet), dict(huntrleaks=huntrleaks, use_resources=use_resources, - debug=debug, rerun_failed=verbose3) + debug=debug, output_on_failure=verbose3) ) yield (test, args_tuple) pending = tests_and_args() @@ -613,7 +614,7 @@ else: try: result = runtest(test, verbose, quiet, huntrleaks, debug, - rerun_failed=verbose3) + output_on_failure=verbose3) accumulate_result(test, result) except KeyboardInterrupt: interrupted = True @@ -760,7 +761,7 @@ def runtest(test, verbose, quiet, huntrleaks=False, debug=False, use_resources=None, - rerun_failed=False): + output_on_failure=False): """Run a single test. test -- the name of the test @@ -769,7 +770,7 @@ test_times -- a list of (time, test_name) pairs huntrleaks -- run multiple times to test for leaks; requires a debug build; a triple corresponding to -R's three arguments - rerun_failed -- if true, re-run in verbose mode when failed + output_on_failure -- if true, display test output on failure Returns one of the test result constants: INTERRUPTED KeyboardInterrupt when run under -j @@ -783,27 +784,35 @@ if use_resources is not None: support.use_resources = use_resources try: - if rerun_failed: - support.verbose = True + support.verbose = verbose # Tell tests to be moderately quiet + if output_on_failure: + if runtest.stringio is None: + # Reuse the same instance to all calls to runtest(). Some + # tests keep a reference to sys.stdout or sys.stderr + # (eg. test_argparse). + runtest.stringio = io.StringIO() + + orig_stdout = sys.stdout orig_stderr = sys.stderr - with support.captured_stdout() as stream: - try: - sys.stderr = stream - result = runtest_inner(test, verbose, quiet, huntrleaks, - debug, display_failure=False) - if result[0] == FAILED: - output = stream.getvalue() - orig_stderr.write(output) - orig_stderr.flush() - finally: - sys.stderr = orig_stderr + try: + sys.stdout = runtest.stringio + sys.stderr = runtest.stringio + result = runtest_inner(test, verbose, quiet, huntrleaks, + debug, display_failure=False) + if result[0] == FAILED: + output = stringio.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stdout = orig_stdout + sys.stderr = orig_stderr else: - support.verbose = verbose # Tell tests to be moderately quiet result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=not verbose) return result finally: cleanup_test_droppings(test, verbose) +runtest.stringio = None # Unit tests are supposed to leave the execution environment unchanged # once they complete. But sometimes tests have bugs, especially when -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:26:02 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:26:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_runtest=28=29_reuses_the?= =?utf8?q?_same_io=2EStringIO_instance_for?= Message-ID: http://hg.python.org/cpython/rev/8897c755633b changeset: 71069:8897c755633b parent: 71067:c0afc8d00c0a parent: 71068:6c54c334ea7a user: Victor Stinner date: Wed Jun 29 15:25:40 2011 +0200 summary: (merge 3.2) Issue #12400: runtest() reuses the same io.StringIO instance for all calls * Don't force verbose to True with option -W * Rename rerun_failed variable to output_on_failure files: Lib/test/regrtest.py | 58 ++++++++++++++++++------------- 1 files changed, 34 insertions(+), 24 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -162,23 +162,24 @@ """ import builtins +import errno import faulthandler import getopt +import io import json +import logging import os +import platform import random import re import sys +import sysconfig +import tempfile import time -import errno import traceback +import unittest import warnings -import unittest from inspect import isabstract -import tempfile -import platform -import sysconfig -import logging # Some times __path__ and __file__ are not absolute (e.g. while running from @@ -579,7 +580,8 @@ args_tuple = ( (test, verbose, quiet), dict(huntrleaks=huntrleaks, use_resources=use_resources, - debug=debug, rerun_failed=verbose3, timeout=timeout) + debug=debug, output_on_failure=verbose3, + timeout=timeout) ) yield (test, args_tuple) pending = tests_and_args() @@ -664,7 +666,7 @@ else: try: result = runtest(test, verbose, quiet, huntrleaks, debug, - rerun_failed=verbose3, timeout=timeout) + output_on_failure=verbose3, timeout=timeout) accumulate_result(test, result) except KeyboardInterrupt: interrupted = True @@ -808,7 +810,7 @@ def runtest(test, verbose, quiet, huntrleaks=False, debug=False, use_resources=None, - rerun_failed=False, timeout=None): + output_on_failure=False, timeout=None): """Run a single test. test -- the name of the test @@ -817,7 +819,7 @@ test_times -- a list of (time, test_name) pairs huntrleaks -- run multiple times to test for leaks; requires a debug build; a triple corresponding to -R's three arguments - rerun_failed -- if true, re-run in verbose mode when failed + output_on_failure -- if true, display test output on failure timeout -- dump the traceback and exit if a test takes more than timeout seconds @@ -836,22 +838,29 @@ if use_timeout: faulthandler.dump_tracebacks_later(timeout, exit=True) try: - if rerun_failed: - support.verbose = True + support.verbose = verbose # Tell tests to be moderately quiet + if output_on_failure: + if runtest.stringio is None: + # Reuse the same instance to all calls to runtest(). Some + # tests keep a reference to sys.stdout or sys.stderr + # (eg. test_argparse). + runtest.stringio = io.StringIO() + + orig_stdout = sys.stdout orig_stderr = sys.stderr - with support.captured_stdout() as stream: - try: - sys.stderr = stream - result = runtest_inner(test, verbose, quiet, huntrleaks, - debug, display_failure=False) - if result[0] == FAILED: - output = stream.getvalue() - orig_stderr.write(output) - orig_stderr.flush() - finally: - sys.stderr = orig_stderr + try: + sys.stdout = runtest.stringio + sys.stderr = runtest.stringio + result = runtest_inner(test, verbose, quiet, huntrleaks, + debug, display_failure=False) + if result[0] == FAILED: + output = stringio.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stdout = orig_stdout + sys.stderr = orig_stderr else: - support.verbose = verbose # Tell tests to be moderately quiet result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=not verbose) return result @@ -859,6 +868,7 @@ if use_timeout: faulthandler.cancel_dump_tracebacks_later() cleanup_test_droppings(test, verbose) +runtest.stringio = None # Unit tests are supposed to leave the execution environment unchanged # once they complete. But sometimes tests have bugs, especially when -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:38:48 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:38:48 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_regrtest=2C_force_verbose_mode_to_True_with_option_-W?= Message-ID: http://hg.python.org/cpython/rev/2d07b1b4466a changeset: 71070:2d07b1b4466a branch: 3.2 parent: 71068:6c54c334ea7a user: Victor Stinner date: Wed Jun 29 15:34:48 2011 +0200 summary: Issue #12400: regrtest, force verbose mode to True with option -W If verbose is False, the output is empty. Fix also a typo in a variable name. files: Lib/test/regrtest.py | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -784,29 +784,32 @@ if use_resources is not None: support.use_resources = use_resources try: - support.verbose = verbose # Tell tests to be moderately quiet if output_on_failure: + support.verbose = True + + # Reuse the same instance to all calls to runtest(). Some + # tests keep a reference to sys.stdout or sys.stderr + # (eg. test_argparse). if runtest.stringio is None: - # Reuse the same instance to all calls to runtest(). Some - # tests keep a reference to sys.stdout or sys.stderr - # (eg. test_argparse). runtest.stringio = io.StringIO() + stream = runtest.stringio orig_stdout = sys.stdout orig_stderr = sys.stderr try: - sys.stdout = runtest.stringio - sys.stderr = runtest.stringio + sys.stdout = stream + sys.stderr = stream result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=False) if result[0] == FAILED: - output = stringio.getvalue() + output = stream.getvalue() orig_stderr.write(output) orig_stderr.flush() finally: sys.stdout = orig_stdout sys.stderr = orig_stderr else: + support.verbose = verbose # Tell tests to be moderately quiet result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=not verbose) return result -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:38:49 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:38:49 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_regrtest=2C_force_verbos?= =?utf8?q?e_mode_to_True_with_option_-W?= Message-ID: http://hg.python.org/cpython/rev/561974b760eb changeset: 71071:561974b760eb parent: 71069:8897c755633b parent: 71070:2d07b1b4466a user: Victor Stinner date: Wed Jun 29 15:38:18 2011 +0200 summary: (merge 3.2) Issue #12400: regrtest, force verbose mode to True with option -W If verbose is False, the output is empty. Fix also a typo in a variable name. files: Lib/test/regrtest.py | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -838,29 +838,32 @@ if use_timeout: faulthandler.dump_tracebacks_later(timeout, exit=True) try: - support.verbose = verbose # Tell tests to be moderately quiet if output_on_failure: + support.verbose = True + + # Reuse the same instance to all calls to runtest(). Some + # tests keep a reference to sys.stdout or sys.stderr + # (eg. test_argparse). if runtest.stringio is None: - # Reuse the same instance to all calls to runtest(). Some - # tests keep a reference to sys.stdout or sys.stderr - # (eg. test_argparse). runtest.stringio = io.StringIO() + stream = runtest.stringio orig_stdout = sys.stdout orig_stderr = sys.stderr try: - sys.stdout = runtest.stringio - sys.stderr = runtest.stringio + sys.stdout = stream + sys.stderr = stream result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=False) if result[0] == FAILED: - output = stringio.getvalue() + output = stream.getvalue() orig_stderr.write(output) orig_stderr.flush() finally: sys.stdout = orig_stdout sys.stderr = orig_stderr else: + support.verbose = verbose # Tell tests to be moderately quiet result = runtest_inner(test, verbose, quiet, huntrleaks, debug, display_failure=not verbose) return result -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:54:07 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:54:07 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_test=2Esupport=2Erun=5Fdoctest=28=29_doesn=27t_change_sys=2E?= =?utf8?q?stdout_anymore?= Message-ID: http://hg.python.org/cpython/rev/d8ba59de860a changeset: 71072:d8ba59de860a branch: 3.2 parent: 71070:2d07b1b4466a user: Victor Stinner date: Wed Jun 29 15:52:46 2011 +0200 summary: Issue #12400: test.support.run_doctest() doesn't change sys.stdout anymore regrtest doesn't check that tests doesn't write something to stdout anymore. Don't replace sys.stdout by the original sys.stdout to be able to capture the output for regrtest -W. files: Lib/test/support.py | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1230,16 +1230,9 @@ else: verbosity = None - # Direct doctest output (normally just errors) to real stdout; doctest - # output shouldn't be compared by regrtest. - save_stdout = sys.stdout - sys.stdout = get_original_stdout() - try: - f, t = doctest.testmod(module, verbose=verbosity) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) - finally: - sys.stdout = save_stdout + f, t = doctest.testmod(module, verbose=verbosity) + if f: + raise TestFailed("%d of %d doctests failed" % (f, t)) if verbose: print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 15:54:08 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 15:54:08 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=2312400=3A_test=2Esupport=2Erun=5Fdoctest=28=29_doesn?= =?utf8?q?=27t_change_sys=2Estdout_anymore?= Message-ID: http://hg.python.org/cpython/rev/bb7c9308c846 changeset: 71073:bb7c9308c846 parent: 71071:561974b760eb parent: 71072:d8ba59de860a user: Victor Stinner date: Wed Jun 29 15:53:11 2011 +0200 summary: Issue #12400: test.support.run_doctest() doesn't change sys.stdout anymore regrtest doesn't check that tests doesn't write something to stdout anymore. Don't replace sys.stdout by the original sys.stdout to be able to capture the output for regrtest -W. files: Lib/test/support.py | 13 +++---------- 1 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -1298,16 +1298,9 @@ else: verbosity = None - # Direct doctest output (normally just errors) to real stdout; doctest - # output shouldn't be compared by regrtest. - save_stdout = sys.stdout - sys.stdout = get_original_stdout() - try: - f, t = doctest.testmod(module, verbose=verbosity) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) - finally: - sys.stdout = save_stdout + f, t = doctest.testmod(module, verbose=verbosity) + if f: + raise TestFailed("%d of %d doctests failed" % (f, t)) if verbose: print('doctest (%s) ... %d tests with zero failures' % (module.__name__, t)) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 17:20:39 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 17:20:39 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_Add_missing_import_=28os=29_to_test=5Fkqueue?= Message-ID: http://hg.python.org/cpython/rev/fdb98a7ef9be changeset: 71074:fdb98a7ef9be branch: 3.2 parent: 71072:d8ba59de860a user: Victor Stinner date: Wed Jun 29 17:20:02 2011 +0200 summary: Issue #12400: Add missing import (os) to test_kqueue files: Lib/test/test_kqueue.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -1,11 +1,12 @@ """ Tests for kqueue wrapper. """ +import errno +import os +import select import socket -import errno +import sys import time -import select -import sys import unittest from test import support -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 17:20:40 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 17:20:40 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_Add_missing_import_=28os?= =?utf8?q?=29_to_test=5Fkqueue?= Message-ID: http://hg.python.org/cpython/rev/37877d19c2c9 changeset: 71075:37877d19c2c9 parent: 71073:bb7c9308c846 parent: 71074:fdb98a7ef9be user: Victor Stinner date: Wed Jun 29 17:20:33 2011 +0200 summary: (merge 3.2) Issue #12400: Add missing import (os) to test_kqueue files: Lib/test/test_kqueue.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -1,11 +1,12 @@ """ Tests for kqueue wrapper. """ +import errno +import os +import select import socket -import errno +import sys import time -import select -import sys import unittest from test import support -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 17:30:19 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 17:30:19 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_runtest=28=29_truncates_the_StringIO_stream_before_a_new_tes?= =?utf8?q?t?= Message-ID: http://hg.python.org/cpython/rev/7bd23115b6c4 changeset: 71076:7bd23115b6c4 branch: 3.2 parent: 71074:fdb98a7ef9be user: Victor Stinner date: Wed Jun 29 17:26:38 2011 +0200 summary: Issue #12400: runtest() truncates the StringIO stream before a new test files: Lib/test/regrtest.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -793,6 +793,7 @@ if runtest.stringio is None: runtest.stringio = io.StringIO() stream = runtest.stringio + stream.truncate(0) orig_stdout = sys.stdout orig_stderr = sys.stderr -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 17:30:20 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 17:30:20 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_runtest=28=29_truncates_?= =?utf8?q?the_StringIO_stream_before_a_new?= Message-ID: http://hg.python.org/cpython/rev/fc831c49216d changeset: 71077:fc831c49216d parent: 71075:37877d19c2c9 parent: 71076:7bd23115b6c4 user: Victor Stinner date: Wed Jun 29 17:29:22 2011 +0200 summary: (merge 3.2) Issue #12400: runtest() truncates the StringIO stream before a new test files: Lib/test/regrtest.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -847,6 +847,7 @@ if runtest.stringio is None: runtest.stringio = io.StringIO() stream = runtest.stringio + stream.truncate(0) orig_stdout = sys.stdout orig_stderr = sys.stderr -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 18:12:58 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 18:12:58 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_test=5Fzipimport=5Fsupport_doesn=27t_restore_original_sys=2E?= =?utf8?q?stdout?= Message-ID: http://hg.python.org/cpython/rev/bc2f3fbda7e3 changeset: 71078:bc2f3fbda7e3 branch: 3.2 parent: 71076:7bd23115b6c4 user: Victor Stinner date: Wed Jun 29 18:11:36 2011 +0200 summary: Issue #12400: test_zipimport_support doesn't restore original sys.stdout anymore regrtest doesn't check that a test doesn't output anything anymore. files: Lib/test/test_zipimport_support.py | 31 ++++++----------- 1 files changed, 12 insertions(+), 19 deletions(-) diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -33,26 +33,19 @@ def _run_object_doctest(obj, module): - # Direct doctest output (normally just errors) to real stdout; doctest - # output shouldn't be compared by regrtest. - save_stdout = sys.stdout - sys.stdout = test.support.get_original_stdout() + finder = doctest.DocTestFinder(verbose=verbose, recurse=False) + runner = doctest.DocTestRunner(verbose=verbose) + # Use the object's fully qualified name if it has one + # Otherwise, use the module's name try: - finder = doctest.DocTestFinder(verbose=verbose, recurse=False) - runner = doctest.DocTestRunner(verbose=verbose) - # Use the object's fully qualified name if it has one - # Otherwise, use the module's name - try: - name = "%s.%s" % (obj.__module__, obj.__name__) - except AttributeError: - name = module.__name__ - for example in finder.find(obj, name, module): - runner.run(example) - f, t = runner.failures, runner.tries - if f: - raise test.support.TestFailed("%d of %d doctests failed" % (f, t)) - finally: - sys.stdout = save_stdout + name = "%s.%s" % (obj.__module__, obj.__name__) + except AttributeError: + name = module.__name__ + for example in finder.find(obj, name, module): + runner.run(example) + f, t = runner.failures, runner.tries + if f: + raise test.support.TestFailed("%d of %d doctests failed" % (f, t)) if verbose: print ('doctest (%s) ... %d tests with zero failures' % (module.__name__, t)) return f, t -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 18:12:59 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 18:12:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312400=3A_test=5Fzipimport=5Fsuppo?= =?utf8?q?rt_doesn=27t_restore_original?= Message-ID: http://hg.python.org/cpython/rev/ff5abf93db80 changeset: 71079:ff5abf93db80 parent: 71077:fc831c49216d parent: 71078:bc2f3fbda7e3 user: Victor Stinner date: Wed Jun 29 18:12:33 2011 +0200 summary: (merge 3.2) Issue #12400: test_zipimport_support doesn't restore original sys.stdout anymore regrtest doesn't check that a test doesn't output anything anymore. files: Lib/test/test_zipimport_support.py | 31 ++++++----------- 1 files changed, 12 insertions(+), 19 deletions(-) diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -33,26 +33,19 @@ def _run_object_doctest(obj, module): - # Direct doctest output (normally just errors) to real stdout; doctest - # output shouldn't be compared by regrtest. - save_stdout = sys.stdout - sys.stdout = test.support.get_original_stdout() + finder = doctest.DocTestFinder(verbose=verbose, recurse=False) + runner = doctest.DocTestRunner(verbose=verbose) + # Use the object's fully qualified name if it has one + # Otherwise, use the module's name try: - finder = doctest.DocTestFinder(verbose=verbose, recurse=False) - runner = doctest.DocTestRunner(verbose=verbose) - # Use the object's fully qualified name if it has one - # Otherwise, use the module's name - try: - name = "%s.%s" % (obj.__module__, obj.__name__) - except AttributeError: - name = module.__name__ - for example in finder.find(obj, name, module): - runner.run(example) - f, t = runner.failures, runner.tries - if f: - raise test.support.TestFailed("%d of %d doctests failed" % (f, t)) - finally: - sys.stdout = save_stdout + name = "%s.%s" % (obj.__module__, obj.__name__) + except AttributeError: + name = module.__name__ + for example in finder.find(obj, name, module): + runner.run(example) + f, t = runner.failures, runner.tries + if f: + raise test.support.TestFailed("%d of %d doctests failed" % (f, t)) if verbose: print ('doctest (%s) ... %d tests with zero failures' % (module.__name__, t)) return f, t -- Repository URL: http://hg.python.org/cpython From tjreedy at udel.edu Wed Jun 29 19:05:13 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 29 Jun 2011 13:05:13 -0400 Subject: [Python-checkins] cpython (3.2): Issue #12400: runtest() truncates the StringIO stream before a new test In-Reply-To: References: Message-ID: <4E0B5B49.7010905@udel.edu> On 6/29/2011 11:30 AM, victor.stinner wrote: > summary: > Issue #12400: runtest() truncates the StringIO stream before a new test > > files: > Lib/test/regrtest.py | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > > diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py > --- a/Lib/test/regrtest.py > +++ b/Lib/test/regrtest.py > @@ -793,6 +793,7 @@ > if runtest.stringio is None: > runtest.stringio = io.StringIO() > stream = runtest.stringio > + stream.truncate(0) You *MUST* seek to 0 to reset the file position, which I presume is your intention. 'Resize' does not mean what you probably think is does (and what I thought once either ;-). "truncate(size=None) Resize the stream to the given size in bytes (or the current position if size is not specified). The current stream position isn?t changed." >>> s=io.StringIO() >>> s.write('abc') 3 >>> s.truncate(0) 0 >>> s.tell() 3 >>> s.write('abc') 3 >>> s.getvalue() '\x00\x00\x00abc' Terry From tjreedy at udel.edu Wed Jun 29 19:25:59 2011 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 29 Jun 2011 13:25:59 -0400 Subject: [Python-checkins] cpython (3.2): Issue #12400: runtest() truncates the StringIO stream before a new test In-Reply-To: <4E0B5B49.7010905@udel.edu> References: <4E0B5B49.7010905@udel.edu> Message-ID: <4E0B6027.8030502@udel.edu> On 6/29/2011 1:05 PM, Terry Reedy wrote: > On 6/29/2011 11:30 AM, victor.stinner wrote: >> if runtest.stringio is None: >> runtest.stringio = io.StringIO() >> stream = runtest.stringio >> + stream.truncate(0) > > You *MUST* seek to 0 to reset the file position, which I presume is your > intention. 'Resize' does not mean what you probably think is does (and > what I thought once either ;-). > > "truncate(size=None) > Resize the stream to the given size in bytes (or the current position if > size is not specified). The current stream position isn?t changed." > > >>> s=io.StringIO() > >>> s.write('abc') > 3 > >>> s.truncate(0) > 0 > >>> s.tell() > 3 > >>> s.write('abc') > 3 > >>> s.getvalue() > '\x00\x00\x00abc' What I did was wrap .getvalue, .seek, and .truncate in a function (which also tested the gotten value for equality with expected) so that the StringIO object was reset and ready to use at the end of every test (restoring the invariant) and therefore ready at the beginning of every test. If I forget to get,test,and restore at the end of a test, then the next test is screwed, which is good since it catches the bug of omission. The equivalent for runtest would be def _assert_sio_equal(expected): sio = runtest.stringio actual = sio.getvalue() sio.seek(0) sio.truncate() AssertEqual(actual,expected) # or viceversa according to convention Terry From python-checkins at python.org Wed Jun 29 20:03:35 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 20:03:35 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDAw?= =?utf8?q?=3A_regrtest=2Eruntest=28=29_uses_stream=2Eseek=280=29_before_?= =?utf8?b?LnRydW5jYXRlKCk=?= Message-ID: http://hg.python.org/cpython/rev/450209efe272 changeset: 71080:450209efe272 branch: 3.2 parent: 71078:bc2f3fbda7e3 user: Victor Stinner date: Wed Jun 29 20:01:29 2011 +0200 summary: Issue #12400: regrtest.runtest() uses stream.seek(0) before .truncate() .truncate(0) doesn't rewind. files: Lib/test/regrtest.py | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -791,9 +791,12 @@ # tests keep a reference to sys.stdout or sys.stderr # (eg. test_argparse). if runtest.stringio is None: - runtest.stringio = io.StringIO() - stream = runtest.stringio - stream.truncate(0) + stream = io.StringIO() + runtest.stringio = stream + else: + stream = runtest.stringio + stream.seek(0) + stream.truncate() orig_stdout = sys.stdout orig_stderr = sys.stderr -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 20:03:35 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 20:03:35 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiAobWVyZ2UgMy4yKSBJc3N1ZSAjMTI0MDA6IHJlZ3J0ZXN0LnJ1bnRlc3QoKSB1?= =?utf8?q?ses_stream=2Eseek=280=29_before?= Message-ID: http://hg.python.org/cpython/rev/3ce22f1b9540 changeset: 71081:3ce22f1b9540 parent: 71079:ff5abf93db80 parent: 71080:450209efe272 user: Victor Stinner date: Wed Jun 29 20:03:13 2011 +0200 summary: (merge 3.2) Issue #12400: regrtest.runtest() uses stream.seek(0) before .truncate() .truncate(0) doesn't rewind. files: Lib/test/regrtest.py | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -845,9 +845,12 @@ # tests keep a reference to sys.stdout or sys.stderr # (eg. test_argparse). if runtest.stringio is None: - runtest.stringio = io.StringIO() - stream = runtest.stringio - stream.truncate(0) + stream = io.StringIO() + runtest.stringio = stream + else: + stream = runtest.stringio + stream.seek(0) + stream.truncate() orig_stdout = sys.stdout orig_stderr = sys.stderr -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 22:27:44 2011 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 29 Jun 2011 22:27:44 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_remove_VISIT=5F*=5FIN=5FBLO?= =?utf8?q?CK_macros?= Message-ID: http://hg.python.org/cpython/rev/099c7b0f24a6 changeset: 71082:099c7b0f24a6 user: Benjamin Peterson date: Wed Jun 29 15:27:14 2011 -0500 summary: remove VISIT_*_IN_BLOCK macros These are pointless because on error, all blocks will be finalized by symtable_dealloc. files: Python/symtable.c | 51 ++++++---------------------------- 1 files changed, 10 insertions(+), 41 deletions(-) diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1029,12 +1029,6 @@ if (!symtable_visit_ ## TYPE((ST), (V))) \ return 0; -#define VISIT_IN_BLOCK(ST, TYPE, V, S) \ - if (!symtable_visit_ ## TYPE((ST), (V))) { \ - symtable_exit_block((ST), (S)); \ - return 0; \ - } - #define VISIT_SEQ(ST, TYPE, SEQ) { \ int i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ @@ -1045,18 +1039,6 @@ } \ } -#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \ - int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (!symtable_visit_ ## TYPE((ST), elt)) { \ - symtable_exit_block((ST), (S)); \ - return 0; \ - } \ - } \ -} - #define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \ int i; \ asdl_seq *seq = (SEQ); /* avoid variable capture */ \ @@ -1067,18 +1049,6 @@ } \ } -#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \ - int i; \ - asdl_seq *seq = (SEQ); /* avoid variable capture */ \ - for (i = (START); i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (!symtable_visit_ ## TYPE((ST), elt)) { \ - symtable_exit_block((ST), (S)); \ - return 0; \ - } \ - } \ -} - #define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \ int i = 0; \ asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \ @@ -1128,8 +1098,8 @@ FunctionBlock, (void *)s, s->lineno, s->col_offset)) return 0; - VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s); - VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s); + VISIT(st, arguments, s->v.FunctionDef.args); + VISIT_SEQ(st, stmt, s->v.FunctionDef.body); if (!symtable_exit_block(st, s)) return 0; break; @@ -1156,7 +1126,7 @@ } tmp = st->st_private; st->st_private = s->v.ClassDef.name; - VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s); + VISIT_SEQ(st, stmt, s->v.ClassDef.body); st->st_private = tmp; if (!symtable_exit_block(st, s)) return 0; @@ -1337,8 +1307,8 @@ FunctionBlock, (void *)e, e->lineno, e->col_offset)) return 0; - VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e); - VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e); + VISIT(st, arguments, e->v.Lambda.args); + VISIT(st, expr, e->v.Lambda.body); if (!symtable_exit_block(st, (void *)e)) return 0; break; @@ -1658,13 +1628,12 @@ symtable_exit_block(st, (void *)e); return 0; } - VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e); - VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e); - VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension, - generators, 1, (void*)e); + VISIT(st, expr, outermost->target); + VISIT_SEQ(st, expr, outermost->ifs); + VISIT_SEQ_TAIL(st, comprehension, generators, 1); if (value) - VISIT_IN_BLOCK(st, expr, value, (void*)e); - VISIT_IN_BLOCK(st, expr, elt, (void*)e); + VISIT(st, expr, value); + VISIT(st, expr, elt); return symtable_exit_block(st, (void *)e); } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 23:26:31 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 23:26:31 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312400=3A_test=5Ffa?= =?utf8?q?ulthandler_now_uses_sys=2E=5F=5Fstderr=5F=5F?= Message-ID: http://hg.python.org/cpython/rev/c7bed90e4f31 changeset: 71083:c7bed90e4f31 user: Victor Stinner date: Wed Jun 29 23:24:31 2011 +0200 summary: Issue #12400: test_faulthandler now uses sys.__stderr__ instead of open(os.devnull, 'w') files: Lib/test/test_faulthandler.py | 6 +----- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -231,14 +231,12 @@ self.assertNotEqual(exitcode, 0) def test_is_enabled(self): - null_stderr = None orig_stderr = sys.stderr try: # regrtest may replace sys.stderr by io.StringIO object, but # faulthandler.enable() requires that sys.stderr has a fileno() # method - null_stderr = open(os.devnull, 'w') - sys.stderr = null_stderr + sys.stderr = sys.__stderr__ was_enabled = faulthandler.is_enabled() try: @@ -253,8 +251,6 @@ faulthandler.disable() finally: sys.stderr = orig_stderr - if null_stderr is not None: - null_stderr.close() def check_dump_traceback(self, filename): """ -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Wed Jun 29 23:28:15 2011 From: python-checkins at python.org (victor.stinner) Date: Wed, 29 Jun 2011 23:28:15 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_faulthandler=3A_add_missing?= =?utf8?q?_include=2C_pthread=2Eh=2C_for_FreeBSD_6?= Message-ID: http://hg.python.org/cpython/rev/9aa3fcab76f0 changeset: 71084:9aa3fcab76f0 user: Victor Stinner date: Wed Jun 29 23:28:02 2011 +0200 summary: faulthandler: add missing include, pthread.h, for FreeBSD 6 files: Modules/faulthandler.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -4,6 +4,10 @@ #include #include #include +#if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) +#include +#endif + /* Allocate at maximum 100 MB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100*1024*1024) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 00:00:58 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 00:00:58 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312400=3A_test=5Fcp?= =?utf8?q?rofile_now_restores_correctly_the_previous_sys=2Estderr?= Message-ID: http://hg.python.org/cpython/rev/6edb7c153105 changeset: 71085:6edb7c153105 user: Victor Stinner date: Thu Jun 30 00:00:45 2011 +0200 summary: Issue #12400: test_cprofile now restores correctly the previous sys.stderr Copy sys.stderr before replacing it, instead of using sys.__stderr__ files: Lib/test/test_cprofile.py | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -18,16 +18,19 @@ def test_bad_counter_during_dealloc(self): import _lsprof # Must use a file as StringIO doesn't trigger the bug. - with open(TESTFN, 'w') as file: - sys.stderr = file - try: - obj = _lsprof.Profiler(lambda: int) - obj.enable() - obj = _lsprof.Profiler(1) - obj.disable() - finally: - sys.stderr = sys.__stderr__ - unlink(TESTFN) + orig_stderr = sys.stderr + try: + with open(TESTFN, 'w') as file: + sys.stderr = file + try: + obj = _lsprof.Profiler(lambda: int) + obj.enable() + obj = _lsprof.Profiler(1) + obj.disable() + finally: + sys.stderr = orig_stderr + finally: + unlink(TESTFN) def test_main(): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 01:51:37 2011 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 30 Jun 2011 01:51:37 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=282=2E7=29=3A_Fixup_repr_for_?= =?utf8?q?dict=5Fproxy_objects=2E?= Message-ID: http://hg.python.org/cpython/rev/9a0b6c07b488 changeset: 71086:9a0b6c07b488 branch: 2.7 parent: 71055:cdfcd00873cd user: Raymond Hettinger date: Thu Jun 30 00:44:36 2011 +0100 summary: Fixup repr for dict_proxy objects. files: Lib/test/test_descr.py | 4 ++++ Misc/NEWS | 2 ++ Objects/descrobject.c | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4589,6 +4589,10 @@ pass self.C = C + def test_repr(self): + self.assertIn('dict_proxy({', repr(vars(self.C))) + self.assertIn("'meth':", repr(vars(self.C))) + def test_iter_keys(self): # Testing dict-proxy iterkeys... keys = [ key for key in self.C.__dict__.iterkeys() ] diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,8 @@ the following case: sys.stdin.read() stopped with CTRL+d (end of file), raw_input() interrupted by CTRL+c. +- dict_proxy objects now display their contents rather than just the class name. + Library ------- diff --git a/Objects/descrobject.c b/Objects/descrobject.c --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -801,6 +801,20 @@ return PyObject_Str(pp->dict); } +static PyObject * +proxy_repr(proxyobject *pp) +{ + PyObject *dictrepr; + PyObject *result; + + dictrepr = PyObject_Repr(pp->dict); + if (dictrepr == NULL) + return NULL; + result = PyString_FromFormat("dict_proxy(%s)", PyString_AS_STRING(dictrepr)); + Py_DECREF(dictrepr); + return result; +} + static int proxy_traverse(PyObject *self, visitproc visit, void *arg) { @@ -832,7 +846,7 @@ 0, /* tp_getattr */ 0, /* tp_setattr */ (cmpfunc)proxy_compare, /* tp_compare */ - 0, /* tp_repr */ + (reprfunc)proxy_repr, /* tp_repr */ 0, /* tp_as_number */ &proxy_as_sequence, /* tp_as_sequence */ &proxy_as_mapping, /* tp_as_mapping */ -- Repository URL: http://hg.python.org/cpython From solipsis at pitrou.net Thu Jun 30 05:08:39 2011 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 30 Jun 2011 05:08:39 +0200 Subject: [Python-checkins] Daily reference leaks (6edb7c153105): sum=1363 Message-ID: results for 6edb7c153105 on branch "default" -------------------------------------------- test_compile leaked [79, 79, 79] references, sum=237 test_generators leaked [101, 101, 101] references, sum=303 test_global leaked [54, 54, 54] references, sum=162 test_keywordonlyarg leaked [77, 77, 77] references, sum=231 test_packaging leaked [100, 100, 100] references, sum=300 test_pydoc leaked [0, -323, 323] references, sum=0 test_pyexpat leaked [0, 0, -56] references, sum=-56 test_scope leaked [62, 62, 62] references, sum=186 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/cpython/refleaks/reflog2kBbnu', '-x'] From python-checkins at python.org Thu Jun 30 05:53:56 2011 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Jun 2011 05:53:56 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_store_the_current_scope_on_?= =?utf8?q?the_stack_right_away?= Message-ID: http://hg.python.org/cpython/rev/151142c0c5b1 changeset: 71087:151142c0c5b1 parent: 71084:9aa3fcab76f0 user: Benjamin Peterson date: Wed Jun 29 22:52:39 2011 -0500 summary: store the current scope on the stack right away files: Python/symtable.c | 39 ++++++++++++++++------------------ 1 files changed, 18 insertions(+), 21 deletions(-) diff --git a/Python/symtable.c b/Python/symtable.c --- a/Python/symtable.c +++ b/Python/symtable.c @@ -899,17 +899,14 @@ static int symtable_exit_block(struct symtable *st, void *ast) { - Py_ssize_t end; + Py_ssize_t size; - Py_CLEAR(st->st_cur); - end = PyList_GET_SIZE(st->st_stack) - 1; - if (end >= 0) { + st->st_cur = NULL; + size = PyList_GET_SIZE(st->st_stack); + if (size) { st->st_cur = (PySTEntryObject *)PyList_GET_ITEM(st->st_stack, - end); - if (st->st_cur == NULL) - return 0; - Py_INCREF(st->st_cur); - if (PySequence_DelItem(st->st_stack, end) < 0) + size - 2); + if (PyList_SetSlice(st->st_stack, size - 1, size, NULL) < 0) return 0; } return 1; @@ -919,23 +916,23 @@ symtable_enter_block(struct symtable *st, identifier name, _Py_block_ty block, void *ast, int lineno, int col_offset) { - PySTEntryObject *prev = NULL; + PySTEntryObject *prev = NULL, *ste; - if (st->st_cur) { - prev = st->st_cur; - if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) { - return 0; - } - Py_DECREF(st->st_cur); + ste = ste_new(st, name, block, ast, lineno, col_offset); + if (ste == NULL) + return 0; + if (PyList_Append(st->st_stack, (PyObject *)ste) < 0) { + Py_DECREF(ste); + return 0; } - st->st_cur = ste_new(st, name, block, ast, lineno, col_offset); - if (st->st_cur == NULL) - return 0; + prev = st->st_cur; + /* The entry is owned by the stack. Borrow it for st_cur. */ + Py_DECREF(ste); + st->st_cur = ste; if (block == ModuleBlock) st->st_global = st->st_cur->ste_symbols; if (prev) { - if (PyList_Append(prev->ste_children, - (PyObject *)st->st_cur) < 0) { + if (PyList_Append(prev->ste_children, (PyObject *)ste) < 0) { return 0; } } -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 05:53:57 2011 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 30 Jun 2011 05:53:57 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_default_-=3E_default?= =?utf8?q?=29=3A_merge_heads?= Message-ID: http://hg.python.org/cpython/rev/c3b487048a0f changeset: 71088:c3b487048a0f parent: 71087:151142c0c5b1 parent: 71085:6edb7c153105 user: Benjamin Peterson date: Wed Jun 29 22:53:19 2011 -0500 summary: merge heads files: Lib/test/test_cprofile.py | 23 +++++++++++++---------- 1 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -18,16 +18,19 @@ def test_bad_counter_during_dealloc(self): import _lsprof # Must use a file as StringIO doesn't trigger the bug. - with open(TESTFN, 'w') as file: - sys.stderr = file - try: - obj = _lsprof.Profiler(lambda: int) - obj.enable() - obj = _lsprof.Profiler(1) - obj.disable() - finally: - sys.stderr = sys.__stderr__ - unlink(TESTFN) + orig_stderr = sys.stderr + try: + with open(TESTFN, 'w') as file: + sys.stderr = file + try: + obj = _lsprof.Profiler(lambda: int) + obj.enable() + obj = _lsprof.Profiler(1) + obj.disable() + finally: + sys.stderr = orig_stderr + finally: + unlink(TESTFN) def test_main(): -- Repository URL: http://hg.python.org/cpython From ncoghlan at gmail.com Thu Jun 30 12:58:52 2011 From: ncoghlan at gmail.com (Nick Coghlan) Date: Thu, 30 Jun 2011 20:58:52 +1000 Subject: [Python-checkins] cpython: store the current scope on the stack right away In-Reply-To: References: Message-ID: On Thu, Jun 30, 2011 at 1:53 PM, benjamin.peterson wrote: > http://hg.python.org/cpython/rev/151142c0c5b1 > changeset: ? 71087:151142c0c5b1 > parent: ? ? ?71084:9aa3fcab76f0 > user: ? ? ? ?Benjamin Peterson > date: ? ? ? ?Wed Jun 29 22:52:39 2011 -0500 > summary: > ?store the current scope on the stack right away Heh, I was going to comment that the spate of refleaks after your previous commit looked mighty suspicious :) End result is simpler, cleaner code overall, though. Cheers, Nick. -- Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia From python-checkins at python.org Thu Jun 30 15:42:02 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 15:42:02 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDUx?= =?utf8?q?=3A_distutils_now_opens_the_setup_script_in_binary_mode_to_read_?= =?utf8?q?the?= Message-ID: http://hg.python.org/cpython/rev/bd73edea78dc changeset: 71089:bd73edea78dc branch: 3.2 parent: 71080:450209efe272 user: Victor Stinner date: Thu Jun 30 15:40:22 2011 +0200 summary: Issue #12451: distutils now opens the setup script in binary mode to read the encoding cookie, instead of opening it in UTF-8. files: Lib/distutils/core.py | 8 +++----- Misc/NEWS | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py --- a/Lib/distutils/core.py +++ b/Lib/distutils/core.py @@ -8,7 +8,8 @@ __revision__ = "$Id$" -import sys, os +import os +import sys from distutils.debug import DEBUG from distutils.errors import * @@ -215,11 +216,8 @@ sys.argv[0] = script_name if script_args is not None: sys.argv[1:] = script_args - f = open(script_name) - try: + with open(script_name, 'rb') as f: exec(f.read(), g, l) - finally: - f.close() finally: sys.argv = save_argv _setup_stop_after = None diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #12451: distutils now opens the setup script in binary mode to read the + encoding cookie, instead of opening it in UTF-8. + - Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the interpreter process. This could cause failures in non-Distutils subprocesses -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 15:42:02 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 15:42:02 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312451=3A_distutils_now_opens_the_?= =?utf8?q?setup_script_in_binary_mode?= Message-ID: http://hg.python.org/cpython/rev/8a7fd54cba01 changeset: 71090:8a7fd54cba01 parent: 71088:c3b487048a0f parent: 71089:bd73edea78dc user: Victor Stinner date: Thu Jun 30 15:41:56 2011 +0200 summary: (merge 3.2) Issue #12451: distutils now opens the setup script in binary mode to read the encoding cookie, instead of opening it in UTF-8. files: Lib/distutils/core.py | 8 +++----- Misc/NEWS | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py --- a/Lib/distutils/core.py +++ b/Lib/distutils/core.py @@ -8,7 +8,8 @@ __revision__ = "$Id$" -import sys, os +import os +import sys from distutils.debug import DEBUG from distutils.errors import * @@ -215,11 +216,8 @@ sys.argv[0] = script_name if script_args is not None: sys.argv[1:] = script_args - f = open(script_name) - try: + with open(script_name, 'rb') as f: exec(f.read(), g, l) - finally: - f.close() finally: sys.argv = save_argv _setup_stop_after = None diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,9 @@ Library ------- +- Issue #12451: distutils now opens the setup script in binary mode to read the + encoding cookie, instead of opening it in UTF-8. + - Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the interpreter process. This could cause failures in non-Distutils subprocesses -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 16:00:04 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 16:00:04 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDUx?= =?utf8?q?=3A_pydoc=2Esynopsis=28=29_now_reads_the_encoding_cookie_if_avai?= =?utf8?q?lable=2C_to?= Message-ID: http://hg.python.org/cpython/rev/1942f7c8f51c changeset: 71091:1942f7c8f51c branch: 3.2 parent: 71089:bd73edea78dc user: Victor Stinner date: Thu Jun 30 15:55:43 2011 +0200 summary: Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, to read the Python script from the right encoding. files: Lib/pydoc.py | 9 +++++---- Lib/test/test_pydoc.py | 13 ++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -57,16 +57,17 @@ # the current directory is changed with os.chdir(), an incorrect # path will be displayed. -import os -import sys import builtins import imp +import inspect import io -import inspect +import os import pkgutil import platform import re +import sys import time +import tokenize import warnings from collections import deque from reprlib import Repr @@ -227,7 +228,7 @@ if lastupdate < mtime: info = inspect.getmoduleinfo(filename) try: - file = open(filename) + file = tokenize.open(filename) except IOError: # module can't be opened, so skip it return None diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -16,7 +16,7 @@ from collections import namedtuple from contextlib import contextmanager from test.support import TESTFN, forget, rmtree, EnvironmentVarGuard, \ - reap_children, captured_output, captured_stdout + reap_children, captured_output, captured_stdout, unlink from test import pydoc_mod @@ -389,6 +389,17 @@ self.assertIn('_replace', helptext) self.assertIn('_asdict', helptext) + def test_synopsis(self): + self.addCleanup(unlink, TESTFN) + for encoding in ('ISO-8859-1', 'UTF-8'): + with open(TESTFN, 'w', encoding=encoding) as script: + if encoding != 'UTF-8': + print('#coding: {}'.format(encoding), file=script) + print('"""line 1: h\xe9', file=script) + print('line 2: hi"""', file=script) + synopsis = pydoc.synopsis(TESTFN, {}) + self.assertEqual(synopsis, 'line 1: h\xe9') + class TestDescriptions(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, + to read the Python script from the right encoding. + - Issue #12451: distutils now opens the setup script in binary mode to read the encoding cookie, instead of opening it in UTF-8. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 16:00:05 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 16:00:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?b?OiAobWVyZ2UgMy4yKSBJc3N1ZSAjMTI0NTE6IHB5ZG9jLnN5bm9wc2lzKCkgbm93?= =?utf8?q?_reads_the_encoding_cookie_if?= Message-ID: http://hg.python.org/cpython/rev/3e627877b5a9 changeset: 71092:3e627877b5a9 parent: 71090:8a7fd54cba01 parent: 71091:1942f7c8f51c user: Victor Stinner date: Thu Jun 30 15:58:29 2011 +0200 summary: (merge 3.2) Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, to read the Python script from the right encoding. files: Lib/pydoc.py | 9 +++++---- Lib/test/test_pydoc.py | 13 ++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -51,16 +51,17 @@ # the current directory is changed with os.chdir(), an incorrect # path will be displayed. -import os -import sys import builtins import imp +import inspect import io -import inspect +import os import pkgutil import platform import re +import sys import time +import tokenize import warnings from collections import deque from reprlib import Repr @@ -221,7 +222,7 @@ if lastupdate < mtime: info = inspect.getmoduleinfo(filename) try: - file = open(filename) + file = tokenize.open(filename) except IOError: # module can't be opened, so skip it return None diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -16,7 +16,7 @@ from collections import namedtuple from contextlib import contextmanager from test.support import TESTFN, forget, rmtree, EnvironmentVarGuard, \ - reap_children, captured_output, captured_stdout + reap_children, captured_output, captured_stdout, unlink from test import pydoc_mod @@ -395,6 +395,17 @@ self.assertIn('_replace', helptext) self.assertIn('_asdict', helptext) + def test_synopsis(self): + self.addCleanup(unlink, TESTFN) + for encoding in ('ISO-8859-1', 'UTF-8'): + with open(TESTFN, 'w', encoding=encoding) as script: + if encoding != 'UTF-8': + print('#coding: {}'.format(encoding), file=script) + print('"""line 1: h\xe9', file=script) + print('line 2: hi"""', file=script) + synopsis = pydoc.synopsis(TESTFN, {}) + self.assertEqual(synopsis, 'line 1: h\xe9') + class TestDescriptions(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,9 @@ Library ------- +- Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, + to read the Python script from the right encoding. + - Issue #12451: distutils now opens the setup script in binary mode to read the encoding cookie, instead of opening it in UTF-8. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 17:39:41 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 17:39:41 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDUx?= =?utf8?q?=3A_doctest=2Edebug=5Fscript=28=29_doesn=27t_create_a_temporary_?= =?utf8?q?file_anymore_to?= Message-ID: http://hg.python.org/cpython/rev/bafc5c7d24b2 changeset: 71093:bafc5c7d24b2 branch: 3.2 parent: 71091:1942f7c8f51c user: Victor Stinner date: Thu Jun 30 17:35:55 2011 +0200 summary: Issue #12451: doctest.debug_script() doesn't create a temporary file anymore to avoid encoding issues (it used the locale encoding, whereas UTF-8 should be). Remove also an unused import (warnings). files: Lib/doctest.py | 61 ++++++++++++++----------------------- Misc/NEWS | 3 + 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/Lib/doctest.py b/Lib/doctest.py --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -92,10 +92,15 @@ ] import __future__ - -import sys, traceback, inspect, linecache, os, re -import unittest, difflib, pdb, tempfile -import warnings +import difflib +import inspect +import linecache +import os +import pdb +import re +import sys +import traceback +import unittest from io import StringIO from collections import namedtuple @@ -2509,39 +2514,21 @@ "Debug a test script. `src` is the script, as a string." import pdb - # Note that tempfile.NameTemporaryFile() cannot be used. As the - # docs say, a file so created cannot be opened by name a second time - # on modern Windows boxes, and exec() needs to open and read it. - srcfilename = tempfile.mktemp(".py", "doctestdebug") - f = open(srcfilename, 'w') - f.write(src) - f.close() - - try: - if globs: - globs = globs.copy() - else: - globs = {} - - if pm: - try: - with open(srcfilename) as f: - exec(f.read(), globs, globs) - except: - print(sys.exc_info()[1]) - p = pdb.Pdb(nosigint=True) - p.reset() - p.interaction(None, sys.exc_info()[2]) - else: - fp = open(srcfilename) - try: - script = fp.read() - finally: - fp.close() - pdb.Pdb(nosigint=True).run("exec(%r)" % script, globs, globs) - - finally: - os.remove(srcfilename) + if globs: + globs = globs.copy() + else: + globs = {} + + if pm: + try: + exec(src, globs, globs) + except: + print(sys.exc_info()[1]) + p = pdb.Pdb(nosigint=True) + p.reset() + p.interaction(None, sys.exc_info()[2]) + else: + pdb.Pdb(nosigint=True).run("exec(%r)" % src, globs, globs) def debug(module, name, pm=False): """Debug a single doctest docstring. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,9 @@ Library ------- +- Issue #12451: doctest.debug_script() doesn't create a temporary file + anymore to avoid encoding issues. + - Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, to read the Python script from the right encoding. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 17:39:42 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 17:39:42 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312451=3A_doctest=2Edebug=5Fscript?= =?utf8?q?=28=29_doesn=27t_create_a_temporary?= Message-ID: http://hg.python.org/cpython/rev/77c589b27e90 changeset: 71094:77c589b27e90 parent: 71092:3e627877b5a9 parent: 71093:bafc5c7d24b2 user: Victor Stinner date: Thu Jun 30 17:39:17 2011 +0200 summary: (merge 3.2) Issue #12451: doctest.debug_script() doesn't create a temporary file anymore to avoid encoding issues (it used the locale encoding, whereas UTF-8 should be). Remove also an unused import (warnings). files: Lib/doctest.py | 61 ++++++++++++++----------------------- Misc/NEWS | 3 + 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/Lib/doctest.py b/Lib/doctest.py --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -92,10 +92,15 @@ ] import __future__ - -import sys, traceback, inspect, linecache, os, re -import unittest, difflib, pdb, tempfile -import warnings +import difflib +import inspect +import linecache +import os +import pdb +import re +import sys +import traceback +import unittest from io import StringIO from collections import namedtuple @@ -2511,39 +2516,21 @@ "Debug a test script. `src` is the script, as a string." import pdb - # Note that tempfile.NameTemporaryFile() cannot be used. As the - # docs say, a file so created cannot be opened by name a second time - # on modern Windows boxes, and exec() needs to open and read it. - srcfilename = tempfile.mktemp(".py", "doctestdebug") - f = open(srcfilename, 'w') - f.write(src) - f.close() - - try: - if globs: - globs = globs.copy() - else: - globs = {} - - if pm: - try: - with open(srcfilename) as f: - exec(f.read(), globs, globs) - except: - print(sys.exc_info()[1]) - p = pdb.Pdb(nosigint=True) - p.reset() - p.interaction(None, sys.exc_info()[2]) - else: - fp = open(srcfilename) - try: - script = fp.read() - finally: - fp.close() - pdb.Pdb(nosigint=True).run("exec(%r)" % script, globs, globs) - - finally: - os.remove(srcfilename) + if globs: + globs = globs.copy() + else: + globs = {} + + if pm: + try: + exec(src, globs, globs) + except: + print(sys.exc_info()[1]) + p = pdb.Pdb(nosigint=True) + p.reset() + p.interaction(None, sys.exc_info()[2]) + else: + pdb.Pdb(nosigint=True).run("exec(%r)" % src, globs, globs) def debug(module, name, pm=False): """Debug a single doctest docstring. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,9 @@ Library ------- +- Issue #12451: doctest.debug_script() doesn't create a temporary file + anymore to avoid encoding issues. + - Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, to read the Python script from the right encoding. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:11:25 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 18:11:25 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDUx?= =?utf8?q?=3A_The_XInclude_default_loader_of_xml=2Eetree_now_decodes_files?= =?utf8?q?_from?= Message-ID: http://hg.python.org/cpython/rev/45e3dafb3dbe changeset: 71095:45e3dafb3dbe branch: 3.2 parent: 71093:bafc5c7d24b2 user: Victor Stinner date: Thu Jun 30 18:10:14 2011 +0200 summary: Issue #12451: The XInclude default loader of xml.etree now decodes files from UTF-8 instead of the locale encoding if the encoding is not specified. It now also opens XML files for the parser in binary mode instead of the text mode to avoid encoding issues. files: Lib/xml/etree/ElementInclude.py | 9 +++++---- Misc/NEWS | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py --- a/Lib/xml/etree/ElementInclude.py +++ b/Lib/xml/etree/ElementInclude.py @@ -67,7 +67,7 @@ # # @param href Resource reference. # @param parse Parse mode. Either "xml" or "text". -# @param encoding Optional text encoding. +# @param encoding Optional text encoding (UTF-8 by default for "text"). # @return The expanded resource. If the parse mode is "xml", this # is an ElementTree instance. If the parse mode is "text", this # is a Unicode string. If the loader fails, it can return None @@ -75,13 +75,14 @@ # @throws IOError If the loader fails to load the resource. def default_loader(href, parse, encoding=None): - file = open(href) if parse == "xml": + file = open(href, 'rb') data = ElementTree.parse(file).getroot() else: + if not encoding: + encoding = 'UTF-8' + file = open(href, 'r', encoding=encoding) data = file.read() - if encoding: - data = data.decode(encoding) file.close() return data diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,11 @@ Library ------- +- Issue #12451: The XInclude default loader of xml.etree now decodes files from + UTF-8 instead of the locale encoding if the encoding is not specified. It now + also opens XML files for the parser in binary mode instead of the text mode + to avoid encoding issues. + - Issue #12451: doctest.debug_script() doesn't create a temporary file anymore to avoid encoding issues. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:11:26 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 18:11:26 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312451=3A_The_XInclude_default_loa?= =?utf8?q?der_of_xml=2Eetree_now_decodes?= Message-ID: http://hg.python.org/cpython/rev/e8eea84a90dc changeset: 71096:e8eea84a90dc parent: 71094:77c589b27e90 parent: 71095:45e3dafb3dbe user: Victor Stinner date: Thu Jun 30 18:11:18 2011 +0200 summary: (merge 3.2) Issue #12451: The XInclude default loader of xml.etree now decodes files from UTF-8 instead of the locale encoding if the encoding is not specified. It now also opens XML files for the parser in binary mode instead of the text mode to avoid encoding issues. files: Lib/xml/etree/ElementInclude.py | 9 +++++---- Misc/NEWS | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py --- a/Lib/xml/etree/ElementInclude.py +++ b/Lib/xml/etree/ElementInclude.py @@ -67,7 +67,7 @@ # # @param href Resource reference. # @param parse Parse mode. Either "xml" or "text". -# @param encoding Optional text encoding. +# @param encoding Optional text encoding (UTF-8 by default for "text"). # @return The expanded resource. If the parse mode is "xml", this # is an ElementTree instance. If the parse mode is "text", this # is a Unicode string. If the loader fails, it can return None @@ -75,13 +75,14 @@ # @throws IOError If the loader fails to load the resource. def default_loader(href, parse, encoding=None): - file = open(href) if parse == "xml": + file = open(href, 'rb') data = ElementTree.parse(file).getroot() else: + if not encoding: + encoding = 'UTF-8' + file = open(href, 'r', encoding=encoding) data = file.read() - if encoding: - data = data.decode(encoding) file.close() return data diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -200,6 +200,11 @@ Library ------- +- Issue #12451: The XInclude default loader of xml.etree now decodes files from + UTF-8 instead of the locale encoding if the encoding is not specified. It now + also opens XML files for the parser in binary mode instead of the text mode + to avoid encoding issues. + - Issue #12451: doctest.debug_script() doesn't create a temporary file anymore to avoid encoding issues. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:21:45 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 18:21:45 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDUx?= =?utf8?q?=3A_Open_files_in_binary_mode_in_some_tests_when_the_text_file_i?= =?utf8?q?s_not?= Message-ID: http://hg.python.org/cpython/rev/68bc1a29ba5a changeset: 71097:68bc1a29ba5a branch: 3.2 parent: 71095:45e3dafb3dbe user: Victor Stinner date: Thu Jun 30 18:20:11 2011 +0200 summary: Issue #12451: Open files in binary mode in some tests when the text file is not needed. Remove also an unused variable (blank) in test_threading. files: Lib/test/test_fcntl.py | 4 ++-- Lib/test/test_ioctl.py | 6 +++--- Lib/test/test_mmap.py | 6 +++--- Lib/test/test_os.py | 13 ++++++------- Lib/test/test_threading.py | 5 ++--- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -62,7 +62,7 @@ def test_fcntl_fileno(self): # the example from the library docs - self.f = open(TESTFN, 'w') + self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) @@ -74,7 +74,7 @@ def test_fcntl_file_descriptor(self): # again, but pass the file rather than numeric descriptor - self.f = open(TESTFN, 'w') + self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK) if sys.platform not in ['os2emx']: rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -7,7 +7,7 @@ get_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature try: - tty = open("/dev/tty", "r") + tty = open("/dev/tty", "rb") except IOError: raise unittest.SkipTest("Unable to open /dev/tty") else: @@ -30,7 +30,7 @@ # If this process has been put into the background, TIOCGPGRP returns # the session ID instead of the process group id. ids = (os.getpgrp(), os.getsid(0)) - with open("/dev/tty", "r") as tty: + with open("/dev/tty", "rb") as tty: r = fcntl.ioctl(tty, termios.TIOCGPGRP, " ") rpgrp = struct.unpack("i", r)[0] self.assertIn(rpgrp, ids) @@ -47,7 +47,7 @@ self.assertEqual(len(buf) * intsize, nbytes) # sanity check else: buf.append(fill) - with open("/dev/tty", "r") as tty: + with open("/dev/tty", "rb") as tty: r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1) rpgrp = buf[0] self.assertEqual(r, 0) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -108,7 +108,7 @@ # Check that the underlying file is truncated too # (bug #728515) - f = open(TESTFN) + f = open(TESTFN, 'rb') try: f.seek(0, 2) self.assertEqual(f.tell(), 512) @@ -308,7 +308,7 @@ f.write(2**16 * b'a') # Arbitrary character f.close() - f = open(TESTFN) + f = open(TESTFN, 'rb') mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ) mf.close() mf.close() @@ -501,7 +501,7 @@ self.assertEqual(m[0:3], b'foo') # Check that the underlying file is truncated too - f = open(TESTFN) + f = open(TESTFN, 'rb') f.seek(0, 2) self.assertEqual(f.tell(), halfsize + 512) f.close() diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -689,12 +689,11 @@ class DevNullTests(unittest.TestCase): def test_devnull(self): - f = open(os.devnull, 'w') - f.write('hello') - f.close() - f = open(os.devnull, 'r') - self.assertEqual(f.read(), '') - f.close() + with open(os.devnull, 'wb') as f: + f.write(b'hello') + f.close() + with open(os.devnull, 'rb') as f: + self.assertEqual(f.read(), b'') class URandomTests(unittest.TestCase): def test_urandom(self): @@ -1044,7 +1043,7 @@ def test_open(self): for fn in self.unicodefn: - f = open(os.path.join(self.dir, fn)) + f = open(os.path.join(self.dir, fn), 'rb') f.close() def test_stat(self): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -642,11 +642,10 @@ def random_io(): '''Loop for a while sleeping random tiny amounts and doing some I/O.''' - blank = b'x' * 200 while True: - in_f = open(os.__file__, 'r') + in_f = open(os.__file__, 'rb') stuff = in_f.read(200) - null_f = open(os.devnull, 'w') + null_f = open(os.devnull, 'wb') null_f.write(stuff) time.sleep(random.random() / 1995) null_f.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:21:45 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 18:21:45 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_=28merge_3=2E2=29_Issue_=2312451=3A_Open_files_in_binary_mod?= =?utf8?q?e_in_some_tests_when_the_text?= Message-ID: http://hg.python.org/cpython/rev/3969b6377f52 changeset: 71098:3969b6377f52 parent: 71096:e8eea84a90dc parent: 71097:68bc1a29ba5a user: Victor Stinner date: Thu Jun 30 18:21:39 2011 +0200 summary: (merge 3.2) Issue #12451: Open files in binary mode in some tests when the text file is not needed. Remove also an unused variable (blank) in test_threading. files: Lib/test/test_fcntl.py | 4 ++-- Lib/test/test_ioctl.py | 6 +++--- Lib/test/test_mmap.py | 6 +++--- Lib/test/test_os.py | 13 ++++++------- Lib/test/test_threading.py | 5 ++--- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -62,7 +62,7 @@ def test_fcntl_fileno(self): # the example from the library docs - self.f = open(TESTFN, 'w') + self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) @@ -74,7 +74,7 @@ def test_fcntl_file_descriptor(self): # again, but pass the file rather than numeric descriptor - self.f = open(TESTFN, 'w') + self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK) if sys.platform not in ['os2emx']: rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py --- a/Lib/test/test_ioctl.py +++ b/Lib/test/test_ioctl.py @@ -7,7 +7,7 @@ get_attribute(termios, 'TIOCGPGRP') #Can't run tests without this feature try: - tty = open("/dev/tty", "r") + tty = open("/dev/tty", "rb") except IOError: raise unittest.SkipTest("Unable to open /dev/tty") else: @@ -30,7 +30,7 @@ # If this process has been put into the background, TIOCGPGRP returns # the session ID instead of the process group id. ids = (os.getpgrp(), os.getsid(0)) - with open("/dev/tty", "r") as tty: + with open("/dev/tty", "rb") as tty: r = fcntl.ioctl(tty, termios.TIOCGPGRP, " ") rpgrp = struct.unpack("i", r)[0] self.assertIn(rpgrp, ids) @@ -47,7 +47,7 @@ self.assertEqual(len(buf) * intsize, nbytes) # sanity check else: buf.append(fill) - with open("/dev/tty", "r") as tty: + with open("/dev/tty", "rb") as tty: r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1) rpgrp = buf[0] self.assertEqual(r, 0) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -108,7 +108,7 @@ # Check that the underlying file is truncated too # (bug #728515) - f = open(TESTFN) + f = open(TESTFN, 'rb') try: f.seek(0, 2) self.assertEqual(f.tell(), 512) @@ -308,7 +308,7 @@ f.write(2**16 * b'a') # Arbitrary character f.close() - f = open(TESTFN) + f = open(TESTFN, 'rb') mf = mmap.mmap(f.fileno(), 2**16, access=mmap.ACCESS_READ) mf.close() mf.close() @@ -530,7 +530,7 @@ self.assertEqual(m[0:3], b'foo') # Check that the underlying file is truncated too - f = open(TESTFN) + f = open(TESTFN, 'rb') f.seek(0, 2) self.assertEqual(f.tell(), halfsize + 512) f.close() diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -694,12 +694,11 @@ class DevNullTests(unittest.TestCase): def test_devnull(self): - f = open(os.devnull, 'w') - f.write('hello') - f.close() - f = open(os.devnull, 'r') - self.assertEqual(f.read(), '') - f.close() + with open(os.devnull, 'wb') as f: + f.write(b'hello') + f.close() + with open(os.devnull, 'rb') as f: + self.assertEqual(f.read(), b'') class URandomTests(unittest.TestCase): def test_urandom(self): @@ -1049,7 +1048,7 @@ def test_open(self): for fn in self.unicodefn: - f = open(os.path.join(self.dir, fn)) + f = open(os.path.join(self.dir, fn), 'rb') f.close() def test_stat(self): diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -650,11 +650,10 @@ def random_io(): '''Loop for a while sleeping random tiny amounts and doing some I/O.''' - blank = b'x' * 200 while True: - in_f = open(os.__file__, 'r') + in_f = open(os.__file__, 'rb') stuff = in_f.read(200) - null_f = open(os.devnull, 'w') + null_f = open(os.devnull, 'wb') null_f.write(stuff) time.sleep(random.random() / 1995) null_f.close() -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:25:28 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 18:25:28 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312451=3A_Open_the_?= =?utf8?q?test_file_in_binary_mode_in_test=5Fbz2=2C_the_text_file_is?= Message-ID: http://hg.python.org/cpython/rev/c4388478f9b2 changeset: 71099:c4388478f9b2 user: Victor Stinner date: Thu Jun 30 18:25:07 2011 +0200 summary: Issue #12451: Open the test file in binary mode in test_bz2, the text file is not needed. files: Lib/test/test_bz2.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -340,7 +340,7 @@ def testFileno(self): self.createTempFile() - with open(self.filename) as rawf: + with open(self.filename, 'rb') as rawf: with BZ2File(fileobj=rawf) as bz2f: self.assertEqual(bz2f.fileno(), rawf.fileno()) -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 18:34:51 2011 From: python-checkins at python.org (giampaolo.rodola) Date: Thu, 30 Jun 2011 18:34:51 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_12139=3A_ftplib_-_rem?= =?utf8?q?ove_=27post_CCC=27_test_to_fix_various_buildot_failures?= Message-ID: http://hg.python.org/cpython/rev/0cef8cac71c8 changeset: 71100:0cef8cac71c8 user: Giampaolo Rodola' date: Thu Jun 30 18:34:41 2011 +0200 summary: Issue 12139: ftplib - remove 'post CCC' test to fix various buildot failures due to dummy test server not properly handling SSL shutdown(), see http://bugs.python.org/msg139499 files: Lib/test/test_ftplib.py | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -887,8 +887,6 @@ self.assertIsInstance(self.client.sock, ssl.SSLSocket) self.client.ccc() self.assertRaises(ValueError, self.client.sock.unwrap) - self.client.sendcmd('noop') - self.client.quit() class TestTimeouts(TestCase): -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 20:03:37 2011 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 30 Jun 2011 20:03:37 +0200 Subject: [Python-checkins] =?utf8?b?Y3B5dGhvbiAoMy4yKTogSXNzdWUgIzEyNDA3?= =?utf8?q?=3A_Explicitly_skip_test=5Fcapi=2EEmbeddingTest_under_Windows=2E?= Message-ID: http://hg.python.org/cpython/rev/7c60c1b41da9 changeset: 71101:7c60c1b41da9 branch: 3.2 parent: 71097:68bc1a29ba5a user: Antoine Pitrou date: Thu Jun 30 20:02:54 2011 +0200 summary: Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. files: Lib/test/test_capi.py | 3 +++ Misc/NEWS | 2 ++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -145,6 +145,9 @@ class EmbeddingTest(unittest.TestCase): + @unittest.skipIf( + sys.platform.startswith('win'), + "test doesn't work under Windows") def test_subinterps(self): # XXX only tested under Unix checkouts basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -136,6 +136,8 @@ Tests ----- +- Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. + - Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures the output and displays it on failure instead. regrtest -v doesn't print the error twice anymore if there is only one error. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 20:05:05 2011 From: python-checkins at python.org (antoine.pitrou) Date: Thu, 30 Jun 2011 20:05:05 +0200 Subject: [Python-checkins] =?utf8?q?cpython_=28merge_3=2E2_-=3E_default=29?= =?utf8?q?=3A_Issue_=2312407=3A_Explicitly_skip_test=5Fcapi=2EEmbeddingTes?= =?utf8?q?t_under_Windows=2E?= Message-ID: http://hg.python.org/cpython/rev/5cae52417b9d changeset: 71102:5cae52417b9d parent: 71100:0cef8cac71c8 parent: 71101:7c60c1b41da9 user: Antoine Pitrou date: Thu Jun 30 20:04:06 2011 +0200 summary: Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. files: Lib/test/test_capi.py | 3 +++ Misc/NEWS | 2 ++ 2 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -145,6 +145,9 @@ class EmbeddingTest(unittest.TestCase): + @unittest.skipIf( + sys.platform.startswith('win'), + "test doesn't work under Windows") def test_subinterps(self): # XXX only tested under Unix checkouts basepath = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -938,6 +938,8 @@ Tests ----- +- Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. + - Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures the output and displays it on failure instead. regrtest -v doesn't print the error twice anymore if there is only one error. -- Repository URL: http://hg.python.org/cpython From python-checkins at python.org Thu Jun 30 23:25:59 2011 From: python-checkins at python.org (victor.stinner) Date: Thu, 30 Jun 2011 23:25:59 +0200 Subject: [Python-checkins] =?utf8?q?cpython=3A_Issue_=2312451=3A_Add_suppo?= =?utf8?q?rt=2Ecreate=5Fempty=5Ffile=28=29?= Message-ID: http://hg.python.org/cpython/rev/0c49260e85a0 changeset: 71103:0c49260e85a0 user: Victor Stinner date: Thu Jun 30 23:25:47 2011 +0200 summary: Issue #12451: Add support.create_empty_file() We don't need to create a temporary buffered binary or text file object just to create an empty file. Replace also os.fdopen(handle).close() by os.close(handle). files: Lib/distutils/tests/test_build_py.py | 6 ++-- Lib/test/support.py | 7 ++++- Lib/test/test_dbm.py | 4 +- Lib/test/test_glob.py | 6 ++-- Lib/test/test_imp.py | 3 +- Lib/test/test_import.py | 4 +- Lib/test/test_mailbox.py | 3 +- Lib/test/test_optparse.py | 2 +- Lib/test/test_os.py | 3 +- Lib/test/test_pkgimport.py | 4 +- Lib/test/test_posix.py | 8 ++-- Lib/test/test_reprlib.py | 23 +++++++-------- Lib/test/test_runpy.py | 12 +++---- Lib/test/test_shutil.py | 5 +-- Lib/test/test_tarfile.py | 6 ++-- Lib/test/test_unicode_file.py | 5 +-- Lib/test/test_zipimport.py | 2 +- 17 files changed, 50 insertions(+), 53 deletions(-) diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py --- a/Lib/distutils/tests/test_build_py.py +++ b/Lib/distutils/tests/test_build_py.py @@ -10,7 +10,7 @@ from distutils.errors import DistutilsFileError from distutils.tests import support -from test.support import run_unittest +from test.support import run_unittest, create_empty_file class BuildPyTestCase(support.TempdirManager, @@ -71,11 +71,11 @@ # create the distribution files. sources = self.mkdtemp() - open(os.path.join(sources, "__init__.py"), "w").close() + create_empty_file(os.path.join(sources, "__init__.py")) testdir = os.path.join(sources, "doc") os.mkdir(testdir) - open(os.path.join(testdir, "testfile"), "w").close() + create_empty_file(os.path.join(testdir, "testfile")) os.chdir(sources) old_stdout = sys.stdout diff --git a/Lib/test/support.py b/Lib/test/support.py --- a/Lib/test/support.py +++ b/Lib/test/support.py @@ -40,7 +40,7 @@ "is_resource_enabled", "requires", "requires_linux_version", "requires_mac_ver", "find_unused_port", "bind_port", "IPV6_ENABLED", "is_jython", "TESTFN", "HOST", "SAVEDCWD", "temp_cwd", - "findfile", "sortdict", "check_syntax_error", "open_urlresource", + "findfile", "create_empty_file", "sortdict", "check_syntax_error", "open_urlresource", "check_warnings", "CleanImport", "EnvironmentVarGuard", "TransientResource", "captured_stdout", "captured_stdin", "captured_stderr", "time_out", "socket_peer_reset", "ioerror_peer_reset", "run_with_locale", 'temp_umask', @@ -596,6 +596,11 @@ if os.path.exists(fn): return fn return file +def create_empty_file(filename): + """Create an empty file. If the file already exists, truncate it.""" + fd = os.open(filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC) + os.close(fd) + def sortdict(dict): "Like repr(dict), but in sorted order." items = sorted(dict.items()) diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -71,8 +71,8 @@ f.close() def test_anydbm_creation_n_file_exists_with_invalid_contents(self): - with open(_fname, "w") as w: - pass # create an empty file + # create an empty file + test.support.create_empty_file(_fname) f = dbm.open(_fname, 'n') self.addCleanup(f.close) diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -1,5 +1,6 @@ import unittest -from test.support import run_unittest, TESTFN, skip_unless_symlink, can_symlink +from test.support import (run_unittest, TESTFN, skip_unless_symlink, + can_symlink, create_empty_file) import glob import os import shutil @@ -14,8 +15,7 @@ base, file = os.path.split(filename) if not os.path.exists(base): os.makedirs(base) - f = open(filename, 'w') - f.close() + create_empty_file(filename) def setUp(self): self.tempdir = TESTFN+"_dir" diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -324,8 +324,7 @@ shutil.rmtree('pep3147') self.addCleanup(cleanup) # Touch the __init__.py file. - with open('pep3147/__init__.py', 'w'): - pass + support.create_empty_file('pep3147/__init__.py') m = __import__('pep3147') # Ensure we load the pyc file. support.forget('pep3147') diff --git a/Lib/test/test_import.py b/Lib/test/test_import.py --- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -14,7 +14,7 @@ from test.support import ( EnvironmentVarGuard, TESTFN, check_warnings, forget, is_jython, make_legacy_pyc, rmtree, run_unittest, swap_attr, swap_item, temp_umask, - unlink, unload) + unlink, unload, create_empty_file) from test import script_helper @@ -103,7 +103,7 @@ sys.path.insert(0, os.curdir) try: fname = TESTFN + os.extsep + "py" - open(fname, 'w').close() + create_empty_file(fname) os.chmod(fname, (stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)) __import__(TESTFN) diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -902,8 +902,7 @@ # Now, write something into cur and remove it. This changes # the mtime and should cause a re-read. filename = os.path.join(self._path, 'cur', 'stray-file') - f = open(filename, 'w') - f.close() + support.create_empty_file(filename) os.unlink(filename) self._box._refresh() self.assertTrue(refreshed()) diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -1023,7 +1023,7 @@ TYPE_CHECKER["file"] = check_file def test_filetype_ok(self): - open(support.TESTFN, "w").close() + support.create_empty_file(support.TESTFN) self.assertParseOK(["--file", support.TESTFN, "-afoo"], {'file': support.TESTFN, 'a': 'foo'}, []) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1028,8 +1028,7 @@ os.mkdir(self.dir) try: for fn in bytesfn: - f = open(os.path.join(self.bdir, fn), "w") - f.close() + support.create_empty_file(os.path.join(self.bdir, fn)) fn = os.fsdecode(fn) if fn in self.unicodefn: raise ValueError("duplicate filename") diff --git a/Lib/test/test_pkgimport.py b/Lib/test/test_pkgimport.py --- a/Lib/test/test_pkgimport.py +++ b/Lib/test/test_pkgimport.py @@ -7,7 +7,7 @@ import unittest from imp import cache_from_source -from test.support import run_unittest +from test.support import run_unittest, create_empty_file class TestImport(unittest.TestCase): @@ -29,7 +29,7 @@ self.package_dir = os.path.join(self.test_dir, self.package_name) os.mkdir(self.package_dir) - open(os.path.join(self.package_dir, '__init__.py'), 'w').close() + create_empty_file(os.path.join(self.package_dir, '__init__.py')) self.module_path = os.path.join(self.package_dir, 'foo.py') def tearDown(self): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -410,7 +410,7 @@ self.assertRaises(OSError, posix.chown, support.TESTFN, -1, -1) # re-create the file - open(support.TESTFN, 'w').close() + support.create_empty_file(support.TESTFN) self._test_all_chown_common(posix.chown, support.TESTFN) @unittest.skipUnless(hasattr(posix, 'fchown'), "test needs os.fchown()") @@ -661,7 +661,7 @@ @unittest.skipUnless(hasattr(posix, 'fchownat'), "test needs posix.fchownat()") def test_fchownat(self): support.unlink(support.TESTFN) - open(support.TESTFN, 'w').close() + support.create_empty_file(support.TESTFN) f = posix.open(posix.getcwd(), posix.O_RDONLY) try: @@ -766,7 +766,7 @@ @unittest.skipUnless(hasattr(posix, 'renameat'), "test needs posix.renameat()") def test_renameat(self): support.unlink(support.TESTFN) - open(support.TESTFN + 'ren', 'w').close() + support.create_empty_file(support.TESTFN + 'ren') f = posix.open(posix.getcwd(), posix.O_RDONLY) try: posix.renameat(f, support.TESTFN + 'ren', f, support.TESTFN) @@ -791,7 +791,7 @@ @unittest.skipUnless(hasattr(posix, 'unlinkat'), "test needs posix.unlinkat()") def test_unlinkat(self): f = posix.open(posix.getcwd(), posix.O_RDONLY) - open(support.TESTFN + 'del', 'w').close() + support.create_empty_file(support.TESTFN + 'del') posix.stat(support.TESTFN + 'del') # should not throw exception try: posix.unlinkat(f, support.TESTFN + 'del') diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -8,7 +8,7 @@ import shutil import unittest -from test.support import run_unittest +from test.support import run_unittest, create_empty_file from reprlib import repr as r # Don't shadow builtin repr from reprlib import Repr from reprlib import recursive_repr @@ -193,10 +193,9 @@ r(y) r(z) -def touch(path, text=''): - fp = open(path, 'w') - fp.write(text) - fp.close() +def write_file(path, text): + with open(path, 'w', encoding='ASCII') as fp: + fp.write(text) class LongReprTest(unittest.TestCase): def setUp(self): @@ -206,10 +205,10 @@ # Make the package and subpackage shutil.rmtree(self.pkgname, ignore_errors=True) os.mkdir(self.pkgname) - touch(os.path.join(self.pkgname, '__init__.py')) + create_empty_file(os.path.join(self.pkgname, '__init__.py')) shutil.rmtree(self.subpkgname, ignore_errors=True) os.mkdir(self.subpkgname) - touch(os.path.join(self.subpkgname, '__init__.py')) + create_empty_file(os.path.join(self.subpkgname, '__init__.py')) # Remember where we are self.here = os.getcwd() sys.path.insert(0, self.here) @@ -231,7 +230,7 @@ def test_module(self): eq = self.assertEqual - touch(os.path.join(self.subpkgname, self.pkgname + '.py')) + create_empty_file(os.path.join(self.subpkgname, self.pkgname + '.py')) from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import areallylongpackageandmodulenametotestreprtruncation eq(repr(areallylongpackageandmodulenametotestreprtruncation), "" % (areallylongpackageandmodulenametotestreprtruncation.__name__, areallylongpackageandmodulenametotestreprtruncation.__file__)) @@ -239,7 +238,7 @@ def test_type(self): eq = self.assertEqual - touch(os.path.join(self.subpkgname, 'foo.py'), '''\ + write_file(os.path.join(self.subpkgname, 'foo.py'), '''\ class foo(object): pass ''') @@ -253,7 +252,7 @@ pass def test_class(self): - touch(os.path.join(self.subpkgname, 'bar.py'), '''\ + write_file(os.path.join(self.subpkgname, 'bar.py'), '''\ class bar: pass ''') @@ -262,7 +261,7 @@ self.assertEqual(repr(bar.bar), "" % bar.__name__) def test_instance(self): - touch(os.path.join(self.subpkgname, 'baz.py'), '''\ + write_file(os.path.join(self.subpkgname, 'baz.py'), '''\ class baz: pass ''') @@ -273,7 +272,7 @@ def test_method(self): eq = self.assertEqual - touch(os.path.join(self.subpkgname, 'qux.py'), '''\ + write_file(os.path.join(self.subpkgname, 'qux.py'), '''\ class aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: def amethod(self): pass ''') diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -7,7 +7,8 @@ import tempfile import py_compile from test.support import ( - forget, make_legacy_pyc, run_unittest, unload, verbose, no_tracing) + forget, make_legacy_pyc, run_unittest, unload, verbose, no_tracing, + create_empty_file) from test.script_helper import ( make_pkg, make_script, make_zip_pkg, make_zip_script, temp_dir) @@ -113,8 +114,7 @@ def _add_pkg_dir(self, pkg_dir): os.mkdir(pkg_dir) pkg_fname = os.path.join(pkg_dir, "__init__.py") - pkg_file = open(pkg_fname, "w") - pkg_file.close() + create_empty_file(pkg_fname) return pkg_fname def _make_pkg(self, source, depth, mod_base="runpy_test"): @@ -219,8 +219,7 @@ module_dir = os.path.join(module_dir, pkg_name) # Add sibling module sibling_fname = os.path.join(module_dir, "sibling.py") - sibling_file = open(sibling_fname, "w") - sibling_file.close() + create_empty_file(sibling_fname) if verbose: print(" Added sibling module:", sibling_fname) # Add nephew module uncle_dir = os.path.join(parent_dir, "uncle") @@ -230,8 +229,7 @@ self._add_pkg_dir(cousin_dir) if verbose: print(" Added cousin package:", cousin_dir) nephew_fname = os.path.join(cousin_dir, "nephew.py") - nephew_file = open(nephew_fname, "w") - nephew_file.close() + create_empty_file(nephew_fname) if verbose: print(" Added nephew module:", nephew_fname) def _check_relative_imports(self, depth, run_name=None): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -107,8 +107,7 @@ self.errorState = 0 os.mkdir(TESTFN) self.childpath = os.path.join(TESTFN, 'a') - f = open(self.childpath, 'w') - f.close() + support.create_empty_file(self.childpath) old_dir_mode = os.stat(TESTFN).st_mode old_child_mode = os.stat(self.childpath).st_mode # Make unwritable. @@ -156,7 +155,7 @@ def test_rmtree_dont_delete_file(self): # When called on a file instead of a directory, don't delete it. handle, path = tempfile.mkstemp() - os.fdopen(handle).close() + os.close(handle) self.assertRaises(OSError, shutil.rmtree, path) os.remove(path) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -893,7 +893,7 @@ try: for name in ("foo", "bar", "baz"): name = os.path.join(tempdir, name) - open(name, "wb").close() + support.create_empty_file(name) exclude = os.path.isfile @@ -920,7 +920,7 @@ try: for name in ("foo", "bar", "baz"): name = os.path.join(tempdir, name) - open(name, "wb").close() + support.create_empty_file(name) def filter(tarinfo): if os.path.basename(tarinfo.name) == "bar": @@ -959,7 +959,7 @@ # and compare the stored name with the original. foo = os.path.join(TEMPDIR, "foo") if not dir: - open(foo, "w").close() + support.create_empty_file(foo) else: os.mkdir(foo) diff --git a/Lib/test/test_unicode_file.py b/Lib/test/test_unicode_file.py --- a/Lib/test/test_unicode_file.py +++ b/Lib/test/test_unicode_file.py @@ -6,7 +6,7 @@ import unittest from test.support import (run_unittest, rmtree, - TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE) + TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE, create_empty_file) if not os.path.supports_unicode_filenames: try: @@ -99,8 +99,7 @@ # top-level 'test' functions would be if they could take params def _test_single(self, filename): remove_if_exists(filename) - f = open(filename, "w") - f.close() + create_empty_file(filename) try: self._do_single(filename) finally: diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -411,7 +411,7 @@ def testEmptyFile(self): support.unlink(TESTMOD) - open(TESTMOD, 'w+').close() + support.create_empty_file(TESTMOD) self.assertZipFailure(TESTMOD) def testFileUnreadable(self): -- Repository URL: http://hg.python.org/cpython