Commit 7e20442f authored by Benjamin Peterson's avatar Benjamin Peterson

Merged revisions...

Merged revisions 75264,75268,75293,75318,75391-75392,75436,75478,75971,76003,76058,76140-76141,76231,76380,76428-76429 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r75264 | andrew.kuchling | 2009-10-05 17:30:22 -0500 (Mon, 05 Oct 2009) | 1 line

  Add various items
........
  r75268 | andrew.kuchling | 2009-10-05 17:45:39 -0500 (Mon, 05 Oct 2009) | 1 line

  Remove two notes
........
  r75293 | kristjan.jonsson | 2009-10-09 09:32:19 -0500 (Fri, 09 Oct 2009) | 2 lines

  http://bugs.python.org/issue7029
  a non-default timer wasn't actually used by the individual Tests.
........
  r75318 | benjamin.peterson | 2009-10-10 16:15:58 -0500 (Sat, 10 Oct 2009) | 1 line

  remove script which uses long gone module
........
  r75391 | andrew.kuchling | 2009-10-13 10:49:33 -0500 (Tue, 13 Oct 2009) | 1 line

  Link to PEP
........
  r75392 | andrew.kuchling | 2009-10-13 11:11:49 -0500 (Tue, 13 Oct 2009) | 1 line

  Various link, textual, and markup fixes
........
  r75436 | benjamin.peterson | 2009-10-15 10:39:15 -0500 (Thu, 15 Oct 2009) | 1 line

  don't need to mess up sys.path
........
  r75478 | senthil.kumaran | 2009-10-17 20:58:45 -0500 (Sat, 17 Oct 2009) | 3 lines

  Fix a typo.
........
  r75971 | benjamin.peterson | 2009-10-30 22:56:15 -0500 (Fri, 30 Oct 2009) | 1 line

  add some checks for evaluation order with parenthesis #7210
........
  r76003 | antoine.pitrou | 2009-10-31 19:30:13 -0500 (Sat, 31 Oct 2009) | 6 lines

  Hopefully fix the buildbot problems on test_mailbox, by computing
  the maildir toc cache refresh date before actually refreshing the cache.

  (see #6896)
........
  r76058 | benjamin.peterson | 2009-11-02 10:14:19 -0600 (Mon, 02 Nov 2009) | 1 line

  grant list.index() a more informative error message #7252
........
  r76140 | nick.coghlan | 2009-11-07 02:13:55 -0600 (Sat, 07 Nov 2009) | 1 line

  Add test for runpy.run_module package execution and use something other than logging as the example of a non-executable package
........
  r76141 | nick.coghlan | 2009-11-07 02:15:01 -0600 (Sat, 07 Nov 2009) | 1 line

  Some minor cleanups to private runpy code and docstrings
........
  r76231 | benjamin.peterson | 2009-11-12 17:42:23 -0600 (Thu, 12 Nov 2009) | 1 line

  this main is much more useful
........
  r76380 | antoine.pitrou | 2009-11-18 14:20:46 -0600 (Wed, 18 Nov 2009) | 3 lines

  Mention Giampolo R's new FTP TLS support in the what's new file
........
  r76428 | benjamin.peterson | 2009-11-19 20:15:50 -0600 (Thu, 19 Nov 2009) | 1 line

  turn goto into do while loop
........
  r76429 | benjamin.peterson | 2009-11-19 20:56:43 -0600 (Thu, 19 Nov 2009) | 2 lines

  avoid doing an uneeded import in a function
........
parent cfa714b2
# This is here so I can use 'wh' instead of 'which' in '~/bin/generic_python'
import which
......@@ -25,27 +25,26 @@ For more info about Tk, including pointers to the source, see the Tcl/Tk home
page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and
Unix platforms.
wxWindows
wxWidgets
'''''''''
wxWindows is a portable GUI class library written in C++ that's a portable
interface to various platform-specific libraries; wxWidgets is a Python
interface to wxWindows. wxWindows supports Windows and MacOS; on Unix variants,
it supports both GTk+ and Motif toolkits. wxWindows preserves the look and feel
of the underlying graphics toolkit, and there is quite a rich widget set and
collection of GDI classes. See `the wxWindows page <http://www.wxwindows.org>`_
for more details.
wxWidgets is a GUI class library written in C++ that's a portable
interface to various platform-specific libraries, and that has a
Python interface called `wxPython <http://www.wxpython.org>`__.
`wxWidgets <http://wxwidgets.org>`_ is an extension module that wraps many of
the wxWindows C++ classes, and is quickly gaining popularity amongst Python
developers. You can get wxWidgets as part of the source or CVS distribution of
wxWindows, or directly from its home page.
wxWidgets preserves the look and feel of the
underlying graphics toolkit, and has a large set of widgets and
collection of GDI classes. See `the wxWidgets page
<http://www.wxwidgets.org>`_ for more details.
wxWidgets supports Windows and MacOS; on Unix variants,
it supports both GTk+ and Motif toolkits.
Qt
'''
There are bindings available for the Qt toolkit (`PyQt
<http://www.riverbankcomputing.co.uk/software/pyqt/>`_) and for KDE (PyKDE). If
<http://www.riverbankcomputing.co.uk/software/pyqt/>`_) and for KDE (`PyKDE <http://www.riverbankcomputing.co.uk/software/pykde/intro>`__). If
you're writing open source software, you don't need to pay for PyQt, but if you
want to write proprietary applications, you must buy a PyQt license from
`Riverbank Computing <http://www.riverbankcomputing.co.uk>`_ and (up to Qt 4.4;
......@@ -56,7 +55,7 @@ Gtk+
''''
PyGtk bindings for the `Gtk+ toolkit <http://www.gtk.org>`_ have been
implemented by by James Henstridge; see ftp://ftp.gtk.org/pub/gtk/python/.
implemented by James Henstridge; see <http://www.pygtk.org>.
FLTK
''''
......@@ -85,14 +84,15 @@ What platform-specific GUI toolkits exist for Python?
`The Mac port <http://python.org/download/mac>`_ by Jack Jansen has a rich and
ever-growing set of modules that support the native Mac toolbox calls. The port
includes support for MacOS9 and MacOS X's Carbon libraries. By installing the
`PyObjc Objective-C bridge <http://pyobjc.sourceforge.net>`_, Python programs
can use MacOS X's Cocoa libraries. See the documentation that comes with the Mac
port.
supports MacOS X's Carbon libraries.
By installing the `PyObjc Objective-C bridge
<http://pyobjc.sourceforge.net>`_, Python programs can use MacOS X's
Cocoa libraries. See the documentation that comes with the Mac port.
:ref:`Pythonwin <windows-faq>` by Mark Hammond includes an interface to the
Microsoft Foundation Classes and a Python programming environment using it
that's written mostly in Python.
Microsoft Foundation Classes and a Python programming environment
that's written mostly in Python using the MFC classes.
Tkinter questions
......@@ -105,23 +105,26 @@ Freeze is a tool to create stand-alone applications. When freezing Tkinter
applications, the applications will not be truly stand-alone, as the application
will still need the Tcl and Tk libraries.
One solution is to ship the application with the tcl and tk libraries, and point
One solution is to ship the application with the Tcl and Tk libraries, and point
to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY`
environment variables.
To get truly stand-alone applications, the Tcl scripts that form the library
have to be integrated into the application as well. One tool supporting that is
SAM (stand-alone modules), which is part of the Tix distribution
(http://tix.mne.com). Build Tix with SAM enabled, perform the appropriate call
to Tclsam_init etc inside Python's Modules/tkappinit.c, and link with libtclsam
and libtksam (you might include the Tix libraries as well).
(http://tix.sourceforge.net/).
Build Tix with SAM enabled, perform the appropriate call to
:cfunc:`Tclsam_init`, etc. inside Python's
:file:`Modules/tkappinit.c`, and link with libtclsam and libtksam (you
might include the Tix libraries as well).
Can I have Tk events handled while waiting for I/O?
---------------------------------------------------
Yes, and you don't even need threads! But you'll have to restructure your I/O
code a bit. Tk has the equivalent of Xt's XtAddInput() call, which allows you
code a bit. Tk has the equivalent of Xt's :cfunc:`XtAddInput()` call, which allows you
to register a callback function which will be called from the Tk mainloop when
I/O is possible on a file descriptor. Here's what you need::
......
This diff is collapsed.
......@@ -287,6 +287,5 @@ def interact(banner=None, readfunc=None, local=None):
console.interact(banner)
if __name__ == '__main__':
import pdb
pdb.run("interact()\n")
if __name__ == "__main__":
interact()
......@@ -469,12 +469,21 @@ class Maildir(Mailbox):
def _refresh(self):
"""Update table of contents mapping."""
new_mtime = os.path.getmtime(os.path.join(self._path, 'new'))
cur_mtime = os.path.getmtime(os.path.join(self._path, 'cur'))
if self._last_read is not None:
for subdir in ('new', 'cur'):
mtime = os.path.getmtime(os.path.join(self._path, subdir))
if mtime > self._last_read:
break
else:
return
if (self._last_read is not None and
new_mtime <= self._last_read and cur_mtime <= self._last_read):
return
# We record the current time - 1sec so that, if _refresh() is called
# again in the same second, we will always re-read the mailbox
# just in case it's been modified. (os.path.mtime() only has
# 1sec resolution.) This results in a few unnecessary re-reads
# when _refresh() is called multiple times in the same second,
# but once the clock ticks over, we will only re-read as needed.
now = time.time() - 1
self._toc = {}
def update_dir (subdir):
......@@ -489,14 +498,7 @@ class Maildir(Mailbox):
update_dir('new')
update_dir('cur')
# We record the current time - 1sec so that, if _refresh() is called
# again in the same second, we will always re-read the mailbox
# just in case it's been modified. (os.path.mtime() only has
# 1sec resolution.) This results in a few unnecessary re-reads
# when _refresh() is called multiple times in the same second,
# but once the clock ticks over, we will only re-read as needed.
now = int(time.time() - 1)
self._last_read = time.time() - 1
self._last_read = now
def _lookup(self, key):
"""Use TOC to return subpath for given key, or raise a KeyError."""
......
......@@ -249,7 +249,7 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
dirs.remove('CVS') # don't visit CVS directories
"""
from os.path import join, isdir, islink
islink, join, isdir = path.islink, path.join, path.isdir
# We may not have read permission for top, in which case we can't
# get a list of the files the directory contains. os.walk
......@@ -275,9 +275,9 @@ def walk(top, topdown=True, onerror=None, followlinks=False):
if topdown:
yield top, dirs, nondirs
for name in dirs:
path = join(top, name)
if followlinks or not islink(path):
for x in walk(path, topdown, onerror, followlinks):
new_path = join(top, name)
if followlinks or not islink(new_path):
for x in walk(new_path, topdown, onerror, followlinks):
yield x
if not topdown:
yield top, dirs, nondirs
......
......@@ -62,7 +62,7 @@ class _ModifiedArgv0(object):
def _run_code(code, run_globals, init_globals=None,
mod_name=None, mod_fname=None,
mod_loader=None, pkg_name=None):
"""Helper for _run_module_code"""
"""Helper to run code in nominated namespace"""
if init_globals is not None:
run_globals.update(init_globals)
run_globals.update(__name__ = mod_name,
......@@ -75,7 +75,7 @@ def _run_code(code, run_globals, init_globals=None,
def _run_module_code(code, init_globals=None,
mod_name=None, mod_fname=None,
mod_loader=None, pkg_name=None):
"""Helper for run_module"""
"""Helper to run code in new namespace with sys modified"""
with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname):
mod_globals = temp_module.module.__dict__
_run_code(code, mod_globals, init_globals,
......@@ -103,7 +103,7 @@ def _get_module_details(mod_name):
raise ImportError("No module named %s" % mod_name)
if loader.is_package(mod_name):
if mod_name == "__main__" or mod_name.endswith(".__main__"):
raise ImportError(("Cannot use package as __main__ module"))
raise ImportError("Cannot use package as __main__ module")
try:
pkg_main_name = mod_name + ".__main__"
return _get_module_details(pkg_main_name)
......@@ -116,29 +116,22 @@ def _get_module_details(mod_name):
filename = _get_filename(loader, mod_name)
return mod_name, loader, code, filename
def _get_main_module_details():
# Helper that gives a nicer error message when attempting to
# execute a zipfile or directory by invoking __main__.py
main_name = "__main__"
try:
return _get_module_details(main_name)
except ImportError as exc:
if main_name in str(exc):
raise ImportError("can't find %r module in %r" %
(main_name, sys.path[0]))
raise
# This function is the actual implementation of the -m switch and direct
# execution of zipfiles and directories and is deliberately kept private.
# This avoids a repeat of the situation where run_module() no longer met the
# needs of mainmodule.c, but couldn't be changed because it was public
# XXX ncoghlan: Should this be documented and made public?
# (Current thoughts: don't repeat the mistake that lead to its
# creation when run_module() no longer met the needs of
# mainmodule.c, but couldn't be changed because it was public)
def _run_module_as_main(mod_name, alter_argv=True):
"""Runs the designated module in the __main__ namespace
These __*__ magic variables will be overwritten:
Note that the executed module will have full access to the
__main__ namespace. If this is not desirable, the run_module()
function sbould be used to run the module code in a fresh namespace.
At the very least, these variables in __main__ will be overwritten:
__name__
__file__
__loader__
__package__
"""
try:
if alter_argv or mod_name != "__main__": # i.e. -m switch
......@@ -146,7 +139,16 @@ def _run_module_as_main(mod_name, alter_argv=True):
else: # i.e. directory or zipfile execution
mod_name, loader, code, fname = _get_main_module_details()
except ImportError as exc:
msg = "%s: %s" % (sys.executable, str(exc))
# Try to provide a good error message
# for directories, zip files and the -m switch
if alter_argv:
# For -m switch, just display the exception
info = str(exc)
else:
# For directories/zipfiles, let the user
# know what the code was looking for
info = "can't find '__main__.py' in %r" % sys.argv[0]
msg = "%s: %s" % (sys.executable, info)
sys.exit(msg)
pkg_name = mod_name.rpartition('.')[0]
main_globals = sys.modules["__main__"].__dict__
......@@ -173,6 +175,18 @@ def run_module(mod_name, init_globals=None,
return _run_code(code, {}, init_globals, run_name,
fname, loader, pkg_name)
def _get_main_module_details():
# Helper that gives a nicer error message when attempting to
# execute a zipfile or directory by invoking __main__.py
main_name = "__main__"
try:
return _get_module_details(main_name)
except ImportError as exc:
if main_name in str(exc):
raise ImportError("can't find %r module in %r" %
(main_name, sys.path[0]))
raise
# XXX (ncoghlan): Perhaps expose the C API function
# as imp.get_importer instead of reimplementing it in Python?
......
......@@ -915,6 +915,14 @@ class GrammarTests(unittest.TestCase):
self.assertEqual((6 / 2 if 1 else 3), 3)
self.assertEqual((6 < 4 if 0 else 2), 2)
def test_paren_evaluation(self):
self.assertEqual(16 // (4 // 2), 8)
self.assertEqual((16 // 4) // 2, 2)
self.assertEqual(16 // 4 // 2, 2)
self.assertTrue(False is (2 is 3))
self.assertFalse((False is 2) is 3)
self.assertFalse(False is 2 is 3)
def test_main():
run_unittest(TokenTests, GrammarTests)
......
......@@ -100,8 +100,8 @@ class RunModuleTest(unittest.TestCase):
self.expect_import_error("a.bee")
self.expect_import_error(".howard")
self.expect_import_error("..eaten")
# Package
self.expect_import_error("logging")
# Package without __main__.py
self.expect_import_error("multiprocessing")
def test_library_module(self):
run_module("runpy")
......@@ -113,9 +113,9 @@ class RunModuleTest(unittest.TestCase):
pkg_file.close()
return pkg_fname
def _make_pkg(self, source, depth):
def _make_pkg(self, source, depth, mod_base="runpy_test"):
pkg_name = "__runpy_pkg__"
test_fname = "runpy_test.py"
test_fname = mod_base+os.extsep+"py"
pkg_dir = sub_dir = tempfile.mkdtemp()
if verbose: print(" Package tree in:", sub_dir)
sys.path.insert(0, pkg_dir)
......@@ -130,7 +130,7 @@ class RunModuleTest(unittest.TestCase):
mod_file.write(source)
mod_file.close()
if verbose: print(" Created:", mod_fname)
mod_name = (pkg_name+".")*depth + "runpy_test"
mod_name = (pkg_name+".")*depth + mod_base
return pkg_dir, mod_fname, mod_name
def _del_pkg(self, top, depth, mod_name):
......@@ -179,6 +179,28 @@ class RunModuleTest(unittest.TestCase):
self._del_pkg(pkg_dir, depth, mod_name)
if verbose: print("Module executed successfully")
def _check_package(self, depth):
pkg_dir, mod_fname, mod_name = (
self._make_pkg("x=1\n", depth, "__main__"))
pkg_name, _, _ = mod_name.rpartition(".")
forget(mod_name)
try:
if verbose: print("Running from source:", pkg_name)
d1 = run_module(pkg_name) # Read from source
self.assertTrue("x" in d1)
self.assertTrue(d1["x"] == 1)
del d1 # Ensure __loader__ entry doesn't keep file open
__import__(mod_name)
os.remove(mod_fname)
if verbose: print("Running from compiled:", pkg_name)
d2 = run_module(pkg_name) # Read from bytecode
self.assertTrue("x" in d2)
self.assertTrue(d2["x"] == 1)
del d2 # Ensure __loader__ entry doesn't keep file open
finally:
self._del_pkg(pkg_dir, depth, pkg_name)
if verbose: print("Package executed successfully")
def _add_relative_modules(self, base_dir, source, depth):
if depth <= 1:
raise ValueError("Relative module test needs depth > 1")
......@@ -240,6 +262,11 @@ from ..uncle.cousin import nephew
if verbose: print("Testing package depth:", depth)
self._check_module(depth)
def test_run_package(self):
for depth in range(1, 4):
if verbose: print("Testing package depth:", depth)
self._check_package(depth)
def test_explicit_relative_import(self):
for depth in range(2, 5):
if verbose: print("Testing relative imports at depth:", depth)
......
......@@ -2098,7 +2098,8 @@ static PyObject *
listindex(PyListObject *self, PyObject *args)
{
Py_ssize_t i, start=0, stop=Py_SIZE(self);
PyObject *v;
PyObject *v, *format_tuple, *err_string;
static PyObject *err_format = NULL;
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
_PyEval_SliceIndex, &start,
......@@ -2121,7 +2122,20 @@ listindex(PyListObject *self, PyObject *args)
else if (cmp < 0)
return NULL;
}
PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list");
if (err_format == NULL) {
err_format = PyUnicode_FromString("%r is not in list");
if (err_format == NULL)
return NULL;
}
format_tuple = PyTuple_Pack(1, v);
if (format_tuple == NULL)
return NULL;
err_string = PyUnicode_Format(err_format, format_tuple);
Py_DECREF(format_tuple);
if (err_string == NULL)
return NULL;
PyErr_SetObject(PyExc_ValueError, err_string);
Py_DECREF(err_string);
return NULL;
}
......
......@@ -3802,49 +3802,47 @@ static void
assemble_jump_offsets(struct assembler *a, struct compiler *c)
{
basicblock *b;
int bsize, totsize, extended_arg_count, last_extended_arg_count = 0;
int bsize, totsize, extended_arg_count = 0, last_extended_arg_count;
int i;
/* Compute the size of each block and fixup jump args.
Replace block pointer with position in bytecode. */
start:
totsize = 0;
for (i = a->a_nblocks - 1; i >= 0; i--) {
b = a->a_postorder[i];
bsize = blocksize(b);
b->b_offset = totsize;
totsize += bsize;
}
extended_arg_count = 0;
for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
bsize = b->b_offset;
for (i = 0; i < b->b_iused; i++) {
struct instr *instr = &b->b_instr[i];
/* Relative jumps are computed relative to
the instruction pointer after fetching
the jump instruction.
*/
bsize += instrsize(instr);
if (instr->i_jabs)
instr->i_oparg = instr->i_target->b_offset;
else if (instr->i_jrel) {
int delta = instr->i_target->b_offset - bsize;
instr->i_oparg = delta;
do {
totsize = 0;
for (i = a->a_nblocks - 1; i >= 0; i--) {
b = a->a_postorder[i];
bsize = blocksize(b);
b->b_offset = totsize;
totsize += bsize;
}
last_extended_arg_count = extended_arg_count;
extended_arg_count = 0;
for (b = c->u->u_blocks; b != NULL; b = b->b_list) {
bsize = b->b_offset;
for (i = 0; i < b->b_iused; i++) {
struct instr *instr = &b->b_instr[i];
/* Relative jumps are computed relative to
the instruction pointer after fetching
the jump instruction.
*/
bsize += instrsize(instr);
if (instr->i_jabs)
instr->i_oparg = instr->i_target->b_offset;
else if (instr->i_jrel) {
int delta = instr->i_target->b_offset - bsize;
instr->i_oparg = delta;
}
else
continue;
if (instr->i_oparg > 0xffff)
extended_arg_count++;
}
else
continue;
if (instr->i_oparg > 0xffff)
extended_arg_count++;
}
}
/* XXX: This is an awful hack that could hurt performance, but
on the bright side it should work until we come up
with a better solution.
In the meantime, should the goto be dropped in favor
of a loop?
The issue is that in the first loop blocksize() is called
which calls instrsize() which requires i_oparg be set
appropriately. There is a bootstrap problem because
......@@ -3855,10 +3853,7 @@ start:
ones in jump instructions. So this should converge
fairly quickly.
*/
if (last_extended_arg_count != extended_arg_count) {
last_extended_arg_count = extended_arg_count;
goto start;
}
} while (last_extended_arg_count != extended_arg_count);
}
static PyObject *
......
......@@ -228,7 +228,7 @@ class Test:
raise ValueError('at least one calibration run is required')
self.calibration_runs = calibration_runs
if timer is not None:
timer = timer
self.timer = timer
# Init variables
self.times = []
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment