Commit 99fddf66 authored by Christian Heimes's avatar Christian Heimes

Merged revisions 59822-59841 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r59822 | georg.brandl | 2008-01-07 17:43:47 +0100 (Mon, 07 Jan 2008) | 2 lines

  Restore "somenamedtuple" as the "class" for named tuple attrs.
........
  r59824 | georg.brandl | 2008-01-07 18:09:35 +0100 (Mon, 07 Jan 2008) | 2 lines

  Patch #602345 by Neal Norwitz and me: add -B option and PYTHONDONTWRITEBYTECODE envvar to skip writing bytecode.
........
  r59827 | georg.brandl | 2008-01-07 18:25:53 +0100 (Mon, 07 Jan 2008) | 2 lines

  patch #1668: clarify envvar docs; rename THREADDEBUG to PYTHONTHREADDEBUG.
........
  r59830 | georg.brandl | 2008-01-07 19:16:36 +0100 (Mon, 07 Jan 2008) | 2 lines

  Make Python compile with --disable-unicode.
........
  r59831 | georg.brandl | 2008-01-07 19:23:27 +0100 (Mon, 07 Jan 2008) | 2 lines

  Restructure urllib doc structure.
........
  r59833 | georg.brandl | 2008-01-07 19:41:34 +0100 (Mon, 07 Jan 2008) | 2 lines

  Fix #define ordering.
........
  r59834 | georg.brandl | 2008-01-07 19:47:44 +0100 (Mon, 07 Jan 2008) | 2 lines

  #467924, patch by Alan McIntyre: Add ZipFile.extract and ZipFile.extractall.
........
  r59835 | raymond.hettinger | 2008-01-07 19:52:19 +0100 (Mon, 07 Jan 2008) | 1 line

  Fix inconsistent title levels -- it made the whole doc build crash horribly.
........
  r59836 | georg.brandl | 2008-01-07 19:57:03 +0100 (Mon, 07 Jan 2008) | 2 lines

  Fix two further doc build warnings.
........
  r59837 | georg.brandl | 2008-01-07 20:17:10 +0100 (Mon, 07 Jan 2008) | 2 lines

  Clarify metaclass docs and add example.
........
  r59838 | vinay.sajip | 2008-01-07 20:40:10 +0100 (Mon, 07 Jan 2008) | 1 line

  Added section about adding contextual information to log output.
........
  r59839 | christian.heimes | 2008-01-07 20:58:41 +0100 (Mon, 07 Jan 2008) | 1 line

  Fixed indention problem that caused the second TIPC test to run on systems without TIPC
........
  r59840 | raymond.hettinger | 2008-01-07 21:07:38 +0100 (Mon, 07 Jan 2008) | 1 line

  Cleanup named tuple subclassing example.
........
parent 4c5f0c74
......@@ -382,7 +382,7 @@ Setting the :attr:`default_factory` to :class:`set` makes the
.. _named-tuple-factory:
:func:`namedtuple` Factory Function for Tuples with Named Fields
-----------------------------------------------------------------
----------------------------------------------------------------
Named tuples assign meaning to each position in a tuple and allow for more readable,
self-documenting code. They can be used wherever regular tuples are used, and
......@@ -398,7 +398,7 @@ they add the ability to access fields by name instead of position index.
The *fieldnames* are a single string with each fieldname separated by whitespace
and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames*
can be specified as a list of strings (such as ['x', 'y']).
can be specified with a sequence of strings (such as ['x', 'y']).
Any valid Python identifier may be used for a fieldname except for names
starting with an underscore. Valid identifiers consist of letters, digits,
......@@ -479,7 +479,7 @@ by the :mod:`csv` or :mod:`sqlite3` modules::
In addition to the methods inherited from tuples, named tuples support
three additional methods and one attribute.
.. method:: namedtuple._make(iterable)
.. method:: somenamedtuple._make(iterable)
Class method that makes a new instance from an existing sequence or iterable.
......@@ -489,7 +489,7 @@ three additional methods and one attribute.
>>> Point._make(t)
Point(x=11, y=22)
.. method:: namedtuple._asdict()
.. method:: somenamedtuple._asdict()
Return a new dict which maps field names to their corresponding values:
......@@ -498,7 +498,7 @@ three additional methods and one attribute.
>>> p._asdict()
{'x': 11, 'y': 22}
.. method:: namedtuple._replace(kwargs)
.. method:: somenamedtuple._replace(kwargs)
Return a new instance of the named tuple replacing specified fields with new values:
......@@ -509,9 +509,9 @@ three additional methods and one attribute.
Point(x=33, y=22)
>>> for partnum, record in inventory.items():
... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now())
inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now())
.. attribute:: namedtuple._fields
.. attribute:: somenamedtuple._fields
Tuple of strings listing the field names. This is useful for introspection
and for creating new named tuple types from existing named tuples.
......@@ -527,9 +527,7 @@ three additional methods and one attribute.
Pixel(x=11, y=22, red=128, green=255, blue=0)'
To retrieve a field whose name is stored in a string, use the :func:`getattr`
function:
::
function::
>>> getattr(p, 'x')
11
......@@ -548,13 +546,15 @@ a fixed-width print format::
@property
def hypot(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __repr__(self):
return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot)
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
>>> for p in Point(3,4), Point(14,5), Point(9./7,6):
print p
>>> print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6)
Point(x=3.000, y=4.000, hypot=5.000)
Point(x=2.000, y=5.000, hypot=5.385)
Point(x=1.286, y=6.000, hypot=6.136)
Point: x= 3.000 y= 4.000 hypot= 5.000
Point: x=14.000 y= 5.000 hypot=14.866
Point: x= 1.286 y= 6.000 hypot= 6.136
Another use for subclassing is to replace performance critcal methods with
faster versions that bypass error-checking and localize variable access::
......@@ -564,10 +564,8 @@ faster versions that bypass error-checking and localize variable access::
def _replace(self, _map=map, **kwds):
return self._make(_map(kwds.pop, ('x', 'y'), self))
Default values can be implemented by starting with a prototype instance
and customizing it with :meth:`_replace`:
::
Default values can be implemented by using :meth:`_replace`:: to
customize a prototype instance::
>>> Account = namedtuple('Account', 'owner balance transaction_count')
>>> model_account = Account('<owner name>', 0.0, 0)
......
......@@ -1118,6 +1118,52 @@ This example uses console and file handlers, but you can use any number and
combination of handlers you choose.
.. _context-info:
Adding contextual information to your logging output
----------------------------------------------------
Sometimes you want logging output to contain contextual information in
addition to the parameters passed to the logging call. For example, in a
networked application, it may be desirable to log client-specific information
in the log (e.g. remote client's username, or IP address). Although you could
use the *extra* parameter to achieve this, it's not always convenient to pass
the information in this way. While it might be tempting to create
:class:`Logger` instances on a per-connection basis, this is not a good idea
because these instances are not garbage collected. While this is not a problem
in practice, when the number of :class:`Logger` instances is dependent on the
level of granularity you want to use in logging an application, it could
be hard to manage if the number of :class:`Logger` instances becomes
effectively unbounded.
There are a number of other ways you can pass contextual information to be
output along with logging event information.
* Use an adapter class which has access to the contextual information and
which defines methods :meth:`debug`, :meth:`info` etc. with the same
signatures as used by :class:`Logger`. You instantiate the adapter with a
name, which will be used to create an underlying :class:`Logger` with that
name. In each adpater method, the passed-in message is modified to include
whatever contextual information you want.
* Use something other than a string to pass the message. Although normally
the first argument to a logger method such as :meth:`debug`, :meth:`info`
etc. is usually a string, it can in fact be any object. This object is the
argument to a :func:`str()` call which is made, in
:meth:`LogRecord.getMessage`, to obtain the actual message string. You can
use this behavior to pass an instance which may be initialized with a
logging message, which redefines :meth:__str__ to return a modified version
of that message with the contextual information added.
* Use a specialized :class:`Formatter` subclass to add additional information
to the formatted output. The subclass could, for instance, merge some thread
local contextual information (or contextual information obtained in some
other way) with the output generated by the base :class:`Formatter`.
In each of these three approaches, thread locals can sometimes be a useful way
of passing contextual information without undue coupling between different
parts of your code.
.. _network-logging:
Sending and receiving logging events across a network
......
......@@ -435,8 +435,9 @@ the iteration methods.
One method needs to be defined for container objects to provide iteration
support:
.. XXX duplicated in reference/datamodel!
.. method:: object.__iter__()
.. method:: container.__iter__()
Return an iterator object. The object is required to support the iterator
protocol described below. If a container supports different types of
......
......@@ -438,6 +438,17 @@ always available.
implement a dynamic prompt.
.. data:: dont_write_bytecode
If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the
import of source modules. This value is initially set to ``True`` or ``False``
depending on the ``-B`` command line option and the ``PYTHONDONTWRITEBYTECODE``
environment variable, but you can set it yourself to control bytecode file
generation.
.. versionadded:: 2.6
.. function:: setcheckinterval(interval)
Set the interpreter's "check interval". This integer value determines how often
......
:mod:`urllib` --- Open arbitrary resources by URL
=================================================
......@@ -17,8 +16,8 @@ built-in function :func:`open`, but accepts Universal Resource Locators (URLs)
instead of filenames. Some restrictions apply --- it can only open URLs for
reading, and no seek operations are available.
It defines the following public functions:
High-level interface
--------------------
.. function:: urlopen(url[, data[, proxies]])
......@@ -174,6 +173,9 @@ It defines the following public functions:
:func:`urlretrieve`.
Utility functions
-----------------
.. function:: quote(string[, safe])
Replace special characters in *string* using the ``%xx`` escape. Letters,
......@@ -235,6 +237,9 @@ It defines the following public functions:
to decode *path*.
URL Opener objects
------------------
.. class:: URLopener([proxies[, **x509]])
Base class for opening and reading URLs. Unless you need to support opening
......@@ -260,6 +265,48 @@ It defines the following public functions:
:class:`URLopener` objects will raise an :exc:`IOError` exception if the server
returns an error code.
.. method:: open(fullurl[, data])
Open *fullurl* using the appropriate protocol. This method sets up cache and
proxy information, then calls the appropriate open method with its input
arguments. If the scheme is not recognized, :meth:`open_unknown` is called.
The *data* argument has the same meaning as the *data* argument of
:func:`urlopen`.
.. method:: open_unknown(fullurl[, data])
Overridable interface to open unknown URL types.
.. method:: retrieve(url[, filename[, reporthook[, data]]])
Retrieves the contents of *url* and places it in *filename*. The return value
is a tuple consisting of a local filename and either a
:class:`mimetools.Message` object containing the response headers (for remote
URLs) or ``None`` (for local URLs). The caller must then open and read the
contents of *filename*. If *filename* is not given and the URL refers to a
local file, the input filename is returned. If the URL is non-local and
*filename* is not given, the filename is the output of :func:`tempfile.mktemp`
with a suffix that matches the suffix of the last path component of the input
URL. If *reporthook* is given, it must be a function accepting three numeric
parameters. It will be called after each chunk of data is read from the
network. *reporthook* is ignored for local URLs.
If the *url* uses the :file:`http:` scheme identifier, the optional *data*
argument may be given to specify a ``POST`` request (normally the request type
is ``GET``). The *data* argument must in standard
:mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
function below.
.. attribute:: version
Variable that specifies the user agent of the opener object. To get
:mod:`urllib` to tell servers that it is a particular user agent, set this in a
subclass as a class variable or in the constructor before calling the base
constructor.
.. class:: FancyURLopener(...)
......@@ -289,6 +336,18 @@ It defines the following public functions:
users for the required information on the controlling terminal. A subclass may
override this method to support more appropriate behavior if needed.
The :class:`FancyURLopener` class offers one additional method that should be
overloaded to provide the appropriate behavior:
.. method:: prompt_user_passwd(host, realm)
Return information needed to authenticate the user at the given host in the
specified security realm. The return value should be a tuple, ``(user,
password)``, which can be used for basic authentication.
The implementation prompts for this information on the terminal; an application
should override this method to use an appropriate interaction model in the local
environment.
.. exception:: ContentTooShortError(msg[, content])
......@@ -297,7 +356,9 @@ It defines the following public functions:
*Content-Length* header). The :attr:`content` attribute stores the downloaded
(and supposedly truncated) data.
Restrictions:
:mod:`urllib` Restrictions
--------------------------
.. index::
pair: HTTP; protocol
......@@ -358,75 +419,6 @@ Restrictions:
module :mod:`urlparse`.
.. _urlopener-objs:
URLopener Objects
-----------------
.. sectionauthor:: Skip Montanaro <skip@pobox.com>
:class:`URLopener` and :class:`FancyURLopener` objects have the following
attributes.
.. method:: URLopener.open(fullurl[, data])
Open *fullurl* using the appropriate protocol. This method sets up cache and
proxy information, then calls the appropriate open method with its input
arguments. If the scheme is not recognized, :meth:`open_unknown` is called.
The *data* argument has the same meaning as the *data* argument of
:func:`urlopen`.
.. method:: URLopener.open_unknown(fullurl[, data])
Overridable interface to open unknown URL types.
.. method:: URLopener.retrieve(url[, filename[, reporthook[, data]]])
Retrieves the contents of *url* and places it in *filename*. The return value
is a tuple consisting of a local filename and either a
:class:`mimetools.Message` object containing the response headers (for remote
URLs) or ``None`` (for local URLs). The caller must then open and read the
contents of *filename*. If *filename* is not given and the URL refers to a
local file, the input filename is returned. If the URL is non-local and
*filename* is not given, the filename is the output of :func:`tempfile.mktemp`
with a suffix that matches the suffix of the last path component of the input
URL. If *reporthook* is given, it must be a function accepting three numeric
parameters. It will be called after each chunk of data is read from the
network. *reporthook* is ignored for local URLs.
If the *url* uses the :file:`http:` scheme identifier, the optional *data*
argument may be given to specify a ``POST`` request (normally the request type
is ``GET``). The *data* argument must in standard
:mimetype:`application/x-www-form-urlencoded` format; see the :func:`urlencode`
function below.
.. attribute:: URLopener.version
Variable that specifies the user agent of the opener object. To get
:mod:`urllib` to tell servers that it is a particular user agent, set this in a
subclass as a class variable or in the constructor before calling the base
constructor.
The :class:`FancyURLopener` class offers one additional method that should be
overloaded to provide the appropriate behavior:
.. method:: FancyURLopener.prompt_user_passwd(host, realm)
Return information needed to authenticate the user at the given host in the
specified security realm. The return value should be a tuple, ``(user,
password)``, which can be used for basic authentication.
The implementation prompts for this information on the terminal; an application
should override this method to use an appropriate interaction model in the local
environment.
.. _urllib-examples:
Examples
......
......@@ -173,6 +173,27 @@ ZipFile Objects
operate independently of the ZipFile.
.. method:: ZipFile.extract(member[, path[, pwd]])
Extract a member from the archive to the current working directory, using its
full name. Its file information is extracted as accurately as possible.
*path* specifies a different directory to extract to. *member* can be a
filename or a :class:`ZipInfo` object. *pwd* is the password used for
encrypted files.
.. versionadded:: 2.6
.. method:: ZipFile.extractall([path[, members[, pwd]]])
Extract all members from the archive to the current working directory. *path*
specifies a different directory to extract to. *members* is optional and must
be a subset of the list returned by :meth:`namelist`. *pwd* is the password
used for encrypted files.
.. versionadded:: 2.6
.. method:: ZipFile.printdir()
Print a table of contents for the archive to ``sys.stdout``.
......@@ -237,6 +258,13 @@ ZipFile Objects
created with mode ``'r'`` will raise a :exc:`RuntimeError`. Calling
:meth:`writestr` on a closed ZipFile will raise a :exc:`RuntimeError`.
.. note::
When passing a :class:`ZipInfo` instance as the *zinfo_or_acrname* parameter,
the compression method used will be that specified in the *compress_type*
member of the given :class:`ZipInfo` instance. By default, the
:class:`ZipInfo` constructor sets this member to :const:`ZIP_STORED`.
The following data attribute is also available:
......
......@@ -1086,7 +1086,8 @@ Basic customization
:meth:`__init__` method will not be invoked.
:meth:`__new__` is intended mainly to allow subclasses of immutable types (like
int, str, or tuple) to customize instance creation.
int, str, or tuple) to customize instance creation. It is also commonly
overridden in custom metaclasses in order to customize class creation.
.. method:: object.__init__(self[, ...])
......@@ -1527,7 +1528,7 @@ read into a separate namespace and the value of class name is bound to the
result of ``type(name, bases, dict)``.
When the class definition is read, if *__metaclass__* is defined then the
callable assigned to it will be called instead of :func:`type`. The allows
callable assigned to it will be called instead of :func:`type`. This allows
classes or functions to be written which monitor or alter the class creation
process:
......@@ -1536,7 +1537,21 @@ process:
* Returning an instance of another class -- essentially performing the role of a
factory function.
.. XXX needs to be updated for the "new metaclasses" PEP
These steps will have to be performed in the metaclass's :meth:`__new__` method
-- :meth:`type.__new__` can then be called from this method to create a class
with different properties. This example adds a new element to the class
dictionary before creating the class::
class metacls(type):
def __new__(mcs, name, bases, dict):
dict['foo'] = 'metacls was here'
return type.__new__(mcs, name, bases, dict)
You can of course also override other class methods (or add new methods); for
example defining a custom :meth:`__call__` method in the metaclass allows custom
behavior when the class is called, e.g. not always creating a new instance.
.. data:: __metaclass__
This variable can be any callable accepting arguments for ``name``, ``bases``,
......
......@@ -142,6 +142,14 @@ Miscellaneous options
option is given twice (:option:`-bb`).
.. cmdoption:: -B
If given, Python won't try to write ``.pyc`` or ``.pyo`` files on the
import of source modules. See also :envvar:`PYTHONDONTWRITEBYTECODE`.
.. versionadded:: 2.6
.. cmdoption:: -d
Turn on parser debugging output (for wizards only, depending on compilation
......@@ -284,6 +292,8 @@ Miscellaneous options
Environment variables
---------------------
These environment variables influence Python's behavior.
.. envvar:: PYTHONHOME
Change the location of the standard Python libraries. By default, the
......@@ -299,7 +309,7 @@ Environment variables
.. envvar:: PYTHONPATH
Augments the default search path for module files. The format is the same as
Augment the default search path for module files. The format is the same as
the shell's :envvar:`PATH`: one or more directory pathnames separated by
colons. Non-existent directories are silently ignored.
......@@ -349,6 +359,9 @@ Environment variables
If this is set to a non-empty string it is equivalent to specifying the
:option:`-i` option.
This variable can also be modified by Python code using :data:`os.environ`
to force inspect mode on program termination.
.. envvar:: PYTHONUNBUFFERED
......@@ -368,3 +381,43 @@ Environment variables
If this is set, Python ignores case in :keyword:`import` statements. This
only works on Windows.
.. envvar:: PYTHONDONTWRITEBYTECODE
If this is set, Python won't try to write ``.pyc`` or ``.pyo`` files on the
import of source modules.
.. versionadded:: 2.6
.. envvar:: PYTHONEXECUTABLE
If this environment variable is set, ``sys.argv[0]`` will be set to its
value instead of the value got through the C runtime. Only works on
MacOS X.
Debug-mode variables
~~~~~~~~~~~~~~~~~~~~
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.
.. envvar:: PYTHONTHREADDEBUG
If set, Python will print debug threading debug info.
.. versionchanged:: 2.6
Previously, this variable was called ``THREADDEBUG``.
.. envvar:: PYTHONDUMPREFS
If set, Python will dump objects and reference counts still alive after
shutting down the interpreter.
.. envvar:: PYTHONMALLOCSTATS
If set, Python will print memory allocation statistics every time a new
object arena is created, and on shutdown.
......@@ -17,6 +17,7 @@ PyAPI_DATA(int) Py_FrozenFlag;
PyAPI_DATA(int) Py_TabcheckFlag;
PyAPI_DATA(int) Py_IgnoreEnvironmentFlag;
PyAPI_DATA(int) Py_DivisionWarningFlag;
PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
/* this is a wrapper around getenv() that pays attention to
Py_IgnoreEnvironmentFlag. It should be used for getting variables like
......
......@@ -119,10 +119,11 @@ if __name__ == '__main__':
@property
def hypot(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __repr__(self):
return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot)
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
print(Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6))
for p in Point(3,4), Point(14,5), Point(9./7,6):
print (p)
class Point(namedtuple('Point', 'x y')):
'Point class with optimized _make() and _replace() without error-checking'
......
......@@ -5,7 +5,7 @@ test_cProfile
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.000 1.000 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 io.py:1212(flush)
2 0.000 0.000 0.000 0.000 io.py:1213(flush)
1 0.000 0.000 0.000 0.000 io.py:269(flush)
1 0.000 0.000 0.000 0.000 io.py:656(closed)
1 0.000 0.000 0.000 0.000 io.py:874(flush)
......@@ -30,7 +30,7 @@ test_cProfile
Function called...
ncalls tottime cumtime
<string>:1(<module>) -> 1 0.270 1.000 test_cProfile.py:30(testfunc)
io.py:1212(flush) -> 1 0.000 0.000 io.py:269(flush)
io.py:1213(flush) -> 1 0.000 0.000 io.py:269(flush)
1 0.000 0.000 io.py:874(flush)
io.py:269(flush) ->
io.py:656(closed) ->
......@@ -53,7 +53,7 @@ test_cProfile.py:89(helper2_indirect) -> 2 0.006 0.040
test_cProfile.py:93(helper2) -> 8 0.064 0.080 test_cProfile.py:103(subhelper)
8 0.000 0.008 {hasattr}
{exec} -> 1 0.000 1.000 <string>:1(<module>)
2 0.000 0.000 io.py:1212(flush)
2 0.000 0.000 io.py:1213(flush)
{hasattr} -> 12 0.012 0.012 test_cProfile.py:115(__getattr__)
{method 'append' of 'list' objects} ->
{method 'disable' of '_lsprof.Profiler' objects} ->
......@@ -65,10 +65,10 @@ test_cProfile.py:93(helper2) -> 8 0.064 0.080
Function was called by...
ncalls tottime cumtime
<string>:1(<module>) <- 1 0.000 1.000 {exec}
io.py:1212(flush) <- 2 0.000 0.000 {exec}
io.py:269(flush) <- 1 0.000 0.000 io.py:1212(flush)
io.py:1213(flush) <- 2 0.000 0.000 {exec}
io.py:269(flush) <- 1 0.000 0.000 io.py:1213(flush)
io.py:656(closed) <- 1 0.000 0.000 io.py:874(flush)
io.py:874(flush) <- 1 0.000 0.000 io.py:1212(flush)
io.py:874(flush) <- 1 0.000 0.000 io.py:1213(flush)
test_cProfile.py:103(subhelper) <- 8 0.064 0.080 test_cProfile.py:93(helper2)
test_cProfile.py:115(__getattr__) <- 16 0.016 0.016 test_cProfile.py:103(subhelper)
12 0.012 0.012 {hasattr}
......
......@@ -10,7 +10,7 @@ test_profile
12 0.000 0.000 0.012 0.001 :0(hasattr)
1 0.000 0.000 0.000 0.000 :0(setprofile)
1 0.000 0.000 1.000 1.000 <string>:1(<module>)
2 0.000 0.000 0.000 0.000 io.py:1212(flush)
2 0.000 0.000 0.000 0.000 io.py:1213(flush)
1 0.000 0.000 0.000 0.000 io.py:269(flush)
1 0.000 0.000 0.000 0.000 io.py:656(closed)
1 0.000 0.000 0.000 0.000 io.py:874(flush)
......@@ -33,11 +33,11 @@ Function called...
:0(append) ->
:0(exc_info) ->
:0(exec) -> <string>:1(<module>)(1) 1.000
io.py:1212(flush)(2) 0.000
io.py:1213(flush)(2) 0.000
:0(hasattr) -> test_profile.py:115(__getattr__)(12) 0.028
:0(setprofile) ->
<string>:1(<module>) -> test_profile.py:30(testfunc)(1) 1.000
io.py:1212(flush) -> io.py:269(flush)(1) 0.000
io.py:1213(flush) -> io.py:269(flush)(1) 0.000
io.py:874(flush)(1) 0.000
io.py:269(flush) ->
io.py:656(closed) ->
......@@ -74,10 +74,10 @@ Function was called by...
test_profile.py:93(helper2)(8) 0.400
:0(setprofile) <- profile:0(testfunc())(1) 1.000
<string>:1(<module>) <- :0(exec)(1) 1.000
io.py:1212(flush) <- :0(exec)(2) 1.000
io.py:269(flush) <- io.py:1212(flush)(1) 0.000
io.py:1213(flush) <- :0(exec)(2) 1.000
io.py:269(flush) <- io.py:1213(flush)(1) 0.000
io.py:656(closed) <- io.py:874(flush)(1) 0.000
io.py:874(flush) <- io.py:1212(flush)(1) 0.000
io.py:874(flush) <- io.py:1213(flush)(1) 0.000
profile:0(profiler) <-
profile:0(testfunc()) <- profile:0(profiler)(1) 0.000
test_profile.py:103(subhelper) <- test_profile.py:93(helper2)(8) 0.400
......
......@@ -1215,7 +1215,7 @@ def test_main():
tests.append(TestLinuxAbstractNamespace)
if isTipcAvailable():
tests.append(TIPCTest)
tests.append(TIPCThreadableTest)
tests.append(TIPCThreadableTest)
thread_info = test_support.threading_setup()
test_support.run_unittest(*tests)
......
......@@ -14,6 +14,11 @@ from test.test_support import TESTFN, run_unittest
TESTFN2 = TESTFN + "2"
FIXEDTEST_SIZE = 1000
SMALL_TEST_DATA = [('_ziptest1', '1q2w3e4r5t'),
('ziptest2dir/_ziptest2', 'qawsedrftg'),
('/ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'),
('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')]
class TestsWithSourceFile(unittest.TestCase):
def setUp(self):
self.line_gen = (bytes("Zipfile test line %d. random float: %f" %
......@@ -289,6 +294,57 @@ class TestsWithSourceFile(unittest.TestCase):
self.assertRaises(RuntimeError, zipf.write, TESTFN)
zipf.close()
def testExtract(self):
zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
for fpath, fdata in SMALL_TEST_DATA:
zipfp.writestr(fpath, fdata)
zipfp.close()
zipfp = zipfile.ZipFile(TESTFN2, "r")
for fpath, fdata in SMALL_TEST_DATA:
writtenfile = zipfp.extract(fpath)
# make sure it was written to the right place
if os.path.isabs(fpath):
correctfile = os.path.join(os.getcwd(), fpath[1:])
else:
correctfile = os.path.join(os.getcwd(), fpath)
self.assertEqual(writtenfile, correctfile)
# make sure correct data is in correct file
self.assertEqual(fdata.encode(), open(writtenfile, "rb").read())
os.remove(writtenfile)
zipfp.close()
# remove the test file subdirectories
shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
def testExtractAll(self):
zipfp = zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED)
for fpath, fdata in SMALL_TEST_DATA:
zipfp.writestr(fpath, fdata)
zipfp.close()
zipfp = zipfile.ZipFile(TESTFN2, "r")
zipfp.extractall()
for fpath, fdata in SMALL_TEST_DATA:
if os.path.isabs(fpath):
outfile = os.path.join(os.getcwd(), fpath[1:])
else:
outfile = os.path.join(os.getcwd(), fpath)
self.assertEqual(fdata.encode(), open(outfile, "rb").read())
os.remove(outfile)
zipfp.close()
# remove the test file subdirectories
shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir'))
def tearDown(self):
os.remove(TESTFN)
os.remove(TESTFN2)
......
......@@ -3,7 +3,7 @@ Read and write ZIP files.
XXX references to utf-8 need further investigation.
"""
import struct, os, time, sys
import struct, os, time, sys, shutil
import binascii, io
try:
......@@ -817,6 +817,62 @@ class ZipFile:
zef.set_univ_newlines(True)
return zef
def extract(self, member, path=None, pwd=None):
"""Extract a member from the archive to the current working directory,
using its full name. Its file information is extracted as accurately
as possible. `member' may be a filename or a ZipInfo object. You can
specify a different directory using `path'.
"""
if not isinstance(member, ZipInfo):
member = self.getinfo(member)
if path is None:
path = os.getcwd()
return self._extract_member(member, path, pwd)
def extractall(self, path=None, members=None, pwd=None):
"""Extract all members from the archive to the current working
directory. `path' specifies a different directory to extract to.
`members' is optional and must be a subset of the list returned
by namelist().
"""
if members is None:
members = self.namelist()
for zipinfo in members:
self.extract(zipinfo, path, pwd)
def _extract_member(self, member, targetpath, pwd):
"""Extract the ZipInfo object 'member' to a physical
file on the path targetpath.
"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
if targetpath[-1:] == "/":
targetpath = targetpath[:-1]
# don't include leading "/" from file name if present
if os.path.isabs(member.filename):
targetpath = os.path.join(targetpath, member.filename[1:])
else:
targetpath = os.path.join(targetpath, member.filename)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)
source = self.open(member.filename, pwd=pwd)
target = open(targetpath, "wb")
shutil.copyfileobj(source, target)
source.close()
target.close()
return targetpath
def _writecheck(self, zinfo):
"""Check for errors before writing a file to the archive."""
if zinfo.filename in self.NameToInfo:
......
This diff is collapsed.
......@@ -44,7 +44,7 @@ static char **orig_argv;
static int orig_argc;
/* command line options */
#define BASE_OPTS "bc:dEhim:OStuvVW:xX?"
#define BASE_OPTS "bBc:dEhim:OStuvVW:xX?"
#define PROGRAM_OPTS BASE_OPTS
......@@ -57,9 +57,10 @@ static char *usage_1 = "\
Options and arguments (and corresponding environment variables):\n\
-b : issue warnings about str(bytes_instance), str(buffer_instance)\n\
and comparing bytes/buffer with str. (-bb: issue errors)\n\
-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\
-c cmd : program passed in as string (terminates option list)\n\
-d : debug output from parser; also PYTHONDEBUG=x\n\
-E : ignore environment variables (such as PYTHONPATH)\n\
-E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\
-h : print this help message and exit (also --help)\n\
";
static char *usage_2 = "\
......@@ -88,6 +89,8 @@ Other environment variables:\n\
PYTHONSTARTUP: file executed on interactive startup (no default)\n\
PYTHONPATH : '%c'-separated list of directories prefixed to the\n\
default module search path. The result is sys.path.\n\
";
static char *usage_5 = "\
PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
The default module search path uses %s.\n\
PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
......@@ -106,7 +109,8 @@ usage(int exitcode, char* program)
fprintf(f, usage_1);
fprintf(f, usage_2);
fprintf(f, usage_3);
fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP);
fprintf(f, usage_4, DELIM);
fprintf(f, usage_5, DELIM, PYTHONHOMEHELP);
}
#if defined(__VMS)
if (exitcode == 0) {
......@@ -313,6 +317,10 @@ Py_Main(int argc, char **argv)
Py_OptimizeFlag++;
break;
case 'B':
Py_DontWriteBytecodeFlag++;
break;
case 'S':
Py_NoSiteFlag++;
break;
......
......@@ -954,8 +954,11 @@ load_source_module(char *name, char *pathname, FILE *fp)
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # from %s\n",
name, pathname);
if (cpathname)
write_compiled_module(co, cpathname, mtime);
if (cpathname) {
PyObject *ro = PySys_GetObject("dont_write_bytecode");
if (ro == NULL || !PyObject_IsTrue(ro))
write_compiled_module(co, cpathname, mtime);
}
}
m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
Py_DECREF(co);
......@@ -1604,7 +1607,7 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
FILEFINDBUF3 ffbuf;
APIRET rc;
if (getenv("PYTHONCASEOK") != NULL)
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
rc = DosFindFirst(buf,
......
......@@ -76,6 +76,7 @@ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */
int Py_NoSiteFlag; /* Suppress 'import site' */
int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */
int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
int Py_FrozenFlag; /* Needed by getpath.c */
int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
......@@ -176,6 +177,8 @@ Py_InitializeEx(int install_sigs)
Py_VerboseFlag = add_flag(Py_VerboseFlag, p);
if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')
Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p);
interp = PyInterpreterState_New();
if (interp == NULL)
......
......@@ -1041,6 +1041,9 @@ _PySys_Init(void)
v = Py_BuildValue("(UUU)", "CPython", branch, svn_revision);
PyDict_SetItemString(sysdict, "subversion", v);
Py_XDECREF(v);
PyDict_SetItemString(sysdict, "dont_write_bytecode",
v = PyBool_FromLong(Py_DontWriteBytecodeFlag));
Py_XDECREF(v);
/*
* These release level checks are mutually exclusive and cover
* the field, so don't get too fancy with the pre-processor!
......
......@@ -79,7 +79,7 @@ void
PyThread_init_thread(void)
{
#ifdef Py_DEBUG
char *p = getenv("THREADDEBUG");
char *p = Py_GETENV("PYTHONTHREADDEBUG");
if (p) {
if (*p)
......
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