Commit 1e257550 authored by Stefan Krah's avatar Stefan Krah

Merge.

parents 0e41981c daa06544
......@@ -194,7 +194,7 @@ Glossary
An object exposing a file-oriented API (with methods such as
:meth:`read()` or :meth:`write()`) to an underlying resource. Depending
on the way it was created, a file object can mediate access to a real
on-disk file or to another other type of storage or communication device
on-disk file or to another type of storage or communication device
(for example standard input/output, in-memory buffers, sockets, pipes,
etc.). File objects are also called :dfn:`file-like objects` or
:dfn:`streams`.
......@@ -523,6 +523,20 @@ Glossary
definition), or pass several arguments as a list to a function. See
:term:`argument`.
provisional package
A provisional package is one which has been deliberately excluded from the
standard library's backwards compatibility guarantees. While major
changes to such packages are not expected, as long as they are marked
provisional, backwards incompatible changes (up to and including removal
of the package) may occur if deemed necessary by core developers. Such
changes will not be made gratuitously -- they will occur only if serious
flaws are uncovered that were missed prior to the inclusion of the
package.
This process allows the standard library to continue to evolve over time,
without locking in problematic design errors for extended periods of time.
See :pep:`411` for more details.
Python 3000
Nickname for the Python 3.x release line (coined long ago when the release
of version 3 was something in the distant future.) This is also
......
......@@ -20,10 +20,6 @@ The list of modules described in this chapter is:
doctest.rst
unittest.rst
unittest.mock.rst
unittest.mock-patch.rst
unittest.mock-magicmethods.rst
unittest.mock-helpers.rst
unittest.mock-getting-started.rst
unittest.mock-examples.rst
2to3.rst
test.rst
......@@ -78,11 +78,14 @@ Priority levels (high to low):
Facilities:
:const:`LOG_KERN`, :const:`LOG_USER`, :const:`LOG_MAIL`, :const:`LOG_DAEMON`,
:const:`LOG_AUTH`, :const:`LOG_LPR`, :const:`LOG_NEWS`, :const:`LOG_UUCP`,
:const:`LOG_CRON` and :const:`LOG_LOCAL0` to :const:`LOG_LOCAL7`.
:const:`LOG_CRON`, :const:`LOG_SYSLOG`, :const:`LOG_LOCAL0` to
:const:`LOG_LOCAL7`, and, if defined in ``<syslog.h>``,
:const:`LOG_AUTHPRIV`.
Log options:
:const:`LOG_PID`, :const:`LOG_CONS`, :const:`LOG_NDELAY`, :const:`LOG_NOWAIT`
and :const:`LOG_PERROR` if defined in ``<syslog.h>``.
:const:`LOG_PID`, :const:`LOG_CONS`, :const:`LOG_NDELAY`, and, if defined
in ``<syslog.h>``, :const:`LOG_ODELAY`, :const:`LOG_NOWAIT`, and
:const:`LOG_PERROR`.
Examples
......
......@@ -143,12 +143,14 @@ The module defines the following functions and data items:
.. versionadded:: 3.3
.. function:: clock_gettime(clk_id)
Return the time of the specified clock *clk_id*.
.. versionadded:: 3.3
.. data:: CLOCK_REALTIME
System-wide real-time clock. Setting this clock requires appropriate
......@@ -156,6 +158,7 @@ The module defines the following functions and data items:
.. versionadded:: 3.3
.. data:: CLOCK_MONOTONIC
Clock that cannot be set and represents monotonic time since some
......@@ -163,6 +166,7 @@ The module defines the following functions and data items:
.. versionadded:: 3.3
.. data:: CLOCK_MONOTONIC_RAW
Similar to :data:`CLOCK_MONOTONIC`, but provides access to a raw
......@@ -172,18 +176,21 @@ The module defines the following functions and data items:
.. versionadded:: 3.3
.. data:: CLOCK_PROCESS_CPUTIME_ID
High-resolution per-process timer from the CPU.
.. versionadded:: 3.3
.. data:: CLOCK_THREAD_CPUTIME_ID
Thread-specific CPU-time clock.
.. versionadded:: 3.3
.. function:: ctime([secs])
Convert a time expressed in seconds since the epoch to a string representing
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
:mod:`unittest.mock` --- MagicMock and magic method support
===========================================================
.. module:: unittest.mock
:synopsis: Mock object library.
.. moduleauthor:: Michael Foord <michael@python.org>
.. currentmodule:: unittest.mock
.. versionadded:: 3.3
.. _magic-methods:
Mocking Magic Methods
---------------------
:class:`Mock` supports mocking the Python protocol methods, also known as
"magic methods". This allows mock objects to replace containers or other
objects that implement Python protocols.
Because magic methods are looked up differently from normal methods [#]_, this
support has been specially implemented. This means that only specific magic
methods are supported. The supported list includes *almost* all of them. If
there are any missing that you need please let us know.
You mock magic methods by setting the method you are interested in to a function
or a mock instance. If you are using a function then it *must* take ``self`` as
the first argument [#]_.
>>> def __str__(self):
... return 'fooble'
...
>>> mock = Mock()
>>> mock.__str__ = __str__
>>> str(mock)
'fooble'
>>> mock = Mock()
>>> mock.__str__ = Mock()
>>> mock.__str__.return_value = 'fooble'
>>> str(mock)
'fooble'
>>> mock = Mock()
>>> mock.__iter__ = Mock(return_value=iter([]))
>>> list(mock)
[]
One use case for this is for mocking objects used as context managers in a
`with` statement:
>>> mock = Mock()
>>> mock.__enter__ = Mock(return_value='foo')
>>> mock.__exit__ = Mock(return_value=False)
>>> with mock as m:
... assert m == 'foo'
...
>>> mock.__enter__.assert_called_with()
>>> mock.__exit__.assert_called_with(None, None, None)
Calls to magic methods do not appear in :attr:`~Mock.method_calls`, but they
are recorded in :attr:`~Mock.mock_calls`.
.. note::
If you use the `spec` keyword argument to create a mock then attempting to
set a magic method that isn't in the spec will raise an `AttributeError`.
The full list of supported magic methods is:
* ``__hash__``, ``__sizeof__``, ``__repr__`` and ``__str__``
* ``__dir__``, ``__format__`` and ``__subclasses__``
* ``__floor__``, ``__trunc__`` and ``__ceil__``
* Comparisons: ``__cmp__``, ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``,
``__eq__`` and ``__ne__``
* Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``,
``__contains__``, ``__len__``, ``__iter__``, ``__getslice__``,
``__setslice__``, ``__reversed__`` and ``__missing__``
* Context manager: ``__enter__`` and ``__exit__``
* Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__``
* The numeric methods (including right hand and in-place variants):
``__add__``, ``__sub__``, ``__mul__``, ``__div__``,
``__floordiv__``, ``__mod__``, ``__divmod__``, ``__lshift__``,
``__rshift__``, ``__and__``, ``__xor__``, ``__or__``, and ``__pow__``
* Numeric conversion methods: ``__complex__``, ``__int__``, ``__float__``,
``__index__`` and ``__coerce__``
* Descriptor methods: ``__get__``, ``__set__`` and ``__delete__``
* Pickling: ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``,
``__getnewargs__``, ``__getstate__`` and ``__setstate__``
The following methods exist but are *not* supported as they are either in use
by mock, can't be set dynamically, or can cause problems:
* ``__getattr__``, ``__setattr__``, ``__init__`` and ``__new__``
* ``__prepare__``, ``__instancecheck__``, ``__subclasscheck__``, ``__del__``
Magic Mock
----------
There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`.
.. class:: MagicMock(*args, **kw)
``MagicMock`` is a subclass of :class:`Mock` with default implementations
of most of the magic methods. You can use ``MagicMock`` without having to
configure the magic methods yourself.
The constructor parameters have the same meaning as for :class:`Mock`.
If you use the `spec` or `spec_set` arguments then *only* magic methods
that exist in the spec will be created.
.. class:: NonCallableMagicMock(*args, **kw)
A non-callable version of `MagicMock`.
The constructor parameters have the same meaning as for
:class:`MagicMock`, with the exception of `return_value` and
`side_effect` which have no meaning on a non-callable mock.
The magic methods are setup with `MagicMock` objects, so you can configure them
and use them in the usual way:
>>> mock = MagicMock()
>>> mock[3] = 'fish'
>>> mock.__setitem__.assert_called_with(3, 'fish')
>>> mock.__getitem__.return_value = 'result'
>>> mock[2]
'result'
By default many of the protocol methods are required to return objects of a
specific type. These methods are preconfigured with a default return value, so
that they can be used without you having to do anything if you aren't interested
in the return value. You can still *set* the return value manually if you want
to change the default.
Methods and their defaults:
* ``__lt__``: NotImplemented
* ``__gt__``: NotImplemented
* ``__le__``: NotImplemented
* ``__ge__``: NotImplemented
* ``__int__`` : 1
* ``__contains__`` : False
* ``__len__`` : 1
* ``__iter__`` : iter([])
* ``__exit__`` : False
* ``__complex__`` : 1j
* ``__float__`` : 1.0
* ``__bool__`` : True
* ``__index__`` : 1
* ``__hash__`` : default hash for the mock
* ``__str__`` : default str for the mock
* ``__sizeof__``: default sizeof for the mock
For example:
>>> mock = MagicMock()
>>> int(mock)
1
>>> len(mock)
0
>>> list(mock)
[]
>>> object() in mock
False
The two equality method, `__eq__` and `__ne__`, are special.
They do the default equality comparison on identity, using a side
effect, unless you change their return value to return something else:
>>> MagicMock() == 3
False
>>> MagicMock() != 3
True
>>> mock = MagicMock()
>>> mock.__eq__.return_value = True
>>> mock == 3
True
The return value of `MagicMock.__iter__` can be any iterable object and isn't
required to be an iterator:
>>> mock = MagicMock()
>>> mock.__iter__.return_value = ['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']
If the return value *is* an iterator, then iterating over it once will consume
it and subsequent iterations will result in an empty list:
>>> mock.__iter__.return_value = iter(['a', 'b', 'c'])
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
[]
``MagicMock`` has all of the supported magic methods configured except for some
of the obscure and obsolete ones. You can still set these up if you want.
Magic methods that are supported but not setup by default in ``MagicMock`` are:
* ``__subclasses__``
* ``__dir__``
* ``__format__``
* ``__get__``, ``__set__`` and ``__delete__``
* ``__reversed__`` and ``__missing__``
* ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``,
``__getstate__`` and ``__setstate__``
* ``__getformat__`` and ``__setformat__``
.. [#] Magic methods *should* be looked up on the class rather than the
instance. Different versions of Python are inconsistent about applying this
rule. The supported protocol methods should work with all supported versions
of Python.
.. [#] The function is basically hooked up to the class, but each ``Mock``
instance is kept isolated from the others.
This diff is collapsed.
This diff is collapsed.
......@@ -5,65 +5,40 @@
:synopsis: Implementation of the ElementTree API.
.. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com>
**Source code:** :source:`Lib/xml/etree/ElementTree.py`
--------------
The :class:`Element` type is a flexible container object, designed to store
hierarchical data structures in memory. The type can be described as a cross
between a list and a dictionary.
Each element has a number of properties associated with it:
* a tag which is a string identifying what kind of data this element represents
(the element type, in other words).
* a number of attributes, stored in a Python dictionary.
* a text string.
* an optional tail string.
* a number of child elements, stored in a Python sequence
To create an element instance, use the :class:`Element` constructor or the
:func:`SubElement` factory function.
The :class:`ElementTree` class can be used to wrap an element structure, and
convert it from and to XML.
See http://effbot.org/zone/element-index.htm for tutorials and links to other
docs.
.. versionchanged:: 3.2
The ElementTree API is updated to 1.3. For more information, see
`Introducing ElementTree 1.3
<http://effbot.org/zone/elementtree-13-intro.htm>`_.
The :mod:`xml.etree.ElementTree` module implements a simple and efficient API
for parsing and creating XML data.
.. versionchanged:: 3.3
This module will use a fast implementation whenever available.
The :mod:`xml.etree.cElementTree` module is deprecated.
Tutorial
--------
.. _elementtree-xpath:
This is a short tutorial for using :mod:`xml.etree.ElementTree` (``ET`` in
short). The goal is to demonstrate some of the building blocks and basic
concepts of the module.
XPath support
-------------
XML tree and elements
^^^^^^^^^^^^^^^^^^^^^
This module provides limited support for
`XPath expressions <http://www.w3.org/TR/xpath>`_ for locating elements in a
tree. The goal is to support a small subset of the abbreviated syntax; a full
XPath engine is outside the scope of the module.
XML is an inherently hierarchical data format, and the most natural way to
represent it is with a tree. ``ET`` has two classes for this purpose -
:class:`ElementTree` represents the whole XML document as a tree, and
:class:`Element` represents a single node in this tree. Interactions with
the whole document (reading and writing to/from files) are usually done
on the :class:`ElementTree` level. Interactions with a single XML element
and its sub-elements are done on the :class:`Element` level.
Example
^^^^^^^
.. _elementtree-parsing-xml:
Here's an example that demonstrates some of the XPath capabilities of the
module::
Parsing XML
^^^^^^^^^^^
import xml.etree.ElementTree as ET
We'll be using the following XML document contained in a Python string as the
sample data for this section::
xml = r'''<?xml version="1.0"?>
countrydata = r'''<?xml version="1.0"?>
<data>
<country name="Liechtenshtein">
<rank>1</rank>
......@@ -88,23 +63,121 @@ module::
</data>
'''
tree = ET.fromstring(xml)
First, import the module and parse the data::
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
:func:`fromstring` parses XML from a string directly into an :class:`Element`,
which is the root element of the parsed tree. Other parsing functions may
create an :class:`ElementTree`. Make sure to check the documentation to be
sure.
As an :class:`Element`, ``root`` has a tag and a dictionary of attributes::
>>> root.tag
'data'
>>> root.attrib
{}
It also has children nodes over which we can iterate::
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenshtein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
Children are nested, and we can access specific child nodes by index::
>>> root[0][1].text
'2008'
Finding interesting elements
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:class:`Element` has some useful methods that help iterate recursively over all
the sub-tree below it (its children, their children, and so on). For example,
:meth:`Element.iter`::
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
More sophisticated specification of which elements to look for is possible by
using :ref:`XPath <elementtree-xpath>`.
Building XML documents
^^^^^^^^^^^^^^^^^^^^^^
``ET`` provides a simple way to build XML documents and write them to files.
The :meth:`ElementTree.write` method serves this purpose.
Once created, an :class:`Element` object may be manipulated by directly changing
its fields (such as :attr:`Element.text`), adding and modifying attributes
(:meth:`Element.set` method), as well as adding new children (for example
with :meth:`Element.append`).
The :func:`SubElement` function also provides a convenient way to create new
sub-elements for a given element::
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>
Additional resources
^^^^^^^^^^^^^^^^^^^^
See http://effbot.org/zone/element-index.htm for tutorials and links to other
docs.
.. _elementtree-xpath:
XPath support
-------------
This module provides limited support for
`XPath expressions <http://www.w3.org/TR/xpath>`_ for locating elements in a
tree. The goal is to support a small subset of the abbreviated syntax; a full
XPath engine is outside the scope of the module.
Example
^^^^^^^
Here's an example that demonstrates some of the XPath capabilities of the
module. We'll be using the ``countrydata`` XML document from the
:ref:`Parsing XML <elementtree-parsing-xml>` section::
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
# Top-level elements
tree.findall(".")
root.findall(".")
# All 'neighbor' grand-children of 'country' children of the top-level
# elements
tree.findall("./country/neighbor")
root.findall("./country/neighbor")
# Nodes with name='Singapore' that have a 'year' child
tree.findall(".//year/..[@name='Singapore']")
root.findall(".//year/..[@name='Singapore']")
# 'year' nodes that are children of nodes with name='Singapore'
tree.findall(".//*[@name='Singapore']/year")
root.findall(".//*[@name='Singapore']/year")
# All 'neighbor' nodes that are the second child of their parent
tree.findall(".//neighbor[2]")
root.findall(".//neighbor[2]")
Supported XPath syntax
^^^^^^^^^^^^^^^^^^^^^^
......
......@@ -3,6 +3,9 @@ What's New in IDLE 3.3?
- IDLE can be launched as `python -m idlelib`
- Issue #14409: IDLE doesn't not execute commands from shell,
error with default keybinding for Return. (Patch by Roger Serwy)
- Issue #3573: IDLE hangs when passing invalid command line args
(directory(ies) instead of file(s)).
......
......@@ -596,7 +596,7 @@ class IdleConf:
'<<replace>>': ['<Control-h>'],
'<<goto-line>>': ['<Alt-g>'],
'<<smart-backspace>>': ['<Key-BackSpace>'],
'<<newline-and-indent>>': ['<Key-Return> <Key-KP_Enter>'],
'<<newline-and-indent>>': ['<Key-Return>', '<Key-KP_Enter>'],
'<<smart-indent>>': ['<Key-Tab>'],
'<<indent-region>>': ['<Control-Key-bracketright>'],
'<<dedent-region>>': ['<Control-Key-bracketleft>'],
......
......@@ -559,11 +559,16 @@ class SocketHandler(logging.Handler):
"""
ei = record.exc_info
if ei:
dummy = self.format(record) # just to get traceback text into record.exc_text
record.exc_info = None # to avoid Unpickleable error
s = pickle.dumps(record.__dict__, 1)
if ei:
record.exc_info = ei # for next handler
# just to get traceback text into record.exc_text ...
dummy = self.format(record)
# See issue #14436: If msg or args are objects, they may not be
# available on the receiving end. So we convert the msg % args
# to a string, save it as msg and zap the args.
d = dict(record.__dict__)
d['msg'] = record.getMessage()
d['args'] = None
d['exc_info'] = None
s = pickle.dumps(d, 1)
slen = struct.pack(">L", len(s))
return slen + s
......
......@@ -9,6 +9,7 @@ import re
import sys
import time
import select
import errno
import unittest
from test import support, mock_socket
......
......@@ -1352,17 +1352,20 @@ def patch(
"""
`patch` acts as a function decorator, class decorator or a context
manager. Inside the body of the function or with statement, the `target`
(specified in the form `'package.module.ClassName'`) is patched
with a `new` object. When the function/with statement exits the patch is
undone.
The `target` is imported and the specified attribute patched with the new
object, so it must be importable from the environment you are calling the
decorator from. The target is imported when the decorated function is
executed, not at decoration time.
If `new` is omitted, then a new `MagicMock` is created and passed in as an
extra argument to the decorated function.
is patched with a `new` object. When the function/with statement exits
the patch is undone.
If `new` is omitted, then the target is replaced with a
`MagicMock`. If `patch` is used as a decorator and `new` is
omitted, the created mock is passed in as an extra argument to the
decorated function. If `patch` is used as a context manager the created
mock is returned by the context manager.
`target` should be a string in the form `'package.module.ClassName'`. The
`target` is imported and the specified object replaced with the `new`
object, so the `target` must be importable from the environment you are
calling `patch` from. The target is imported when the decorated function
is executed, not at decoration time.
The `spec` and `spec_set` keyword arguments are passed to the `MagicMock`
if patch is creating one for you.
......
......@@ -832,6 +832,7 @@ Terry Reedy
Gareth Rees
Steve Reeves
Lennart Regebro
Federico Reghenzani
Ofir Reichenberg
Sean Reifschneider
Michael P. Reilly
......
......@@ -34,6 +34,12 @@ Core and Builtins
Library
-------
- Issue #14409: IDLE doesn't not execute commands from shell,
error with default keybinding for Return. (Patch by Roger Serwy)
- Issue #14416: syslog now defines the LOG_ODELAY and LOG_AUTHPRIV constants
if they are defined in <syslog.h>.
- IDLE can be launched as python -m idlelib
- Issue #14295: Add unittest.mock
......@@ -193,6 +199,8 @@ Extension Modules
Tests
-----
- Issue #14442: Add missing errno import in test_smtplib.
- Issue #8315: (partial fix) python -m unittest test.test_email now works.
......
......@@ -291,6 +291,9 @@ PyInit_syslog(void)
PyModule_AddIntConstant(m, "LOG_PID", LOG_PID);
PyModule_AddIntConstant(m, "LOG_CONS", LOG_CONS);
PyModule_AddIntConstant(m, "LOG_NDELAY", LOG_NDELAY);
#ifdef LOG_ODELAY
PyModule_AddIntConstant(m, "LOG_ODELAY", LOG_ODELAY);
#endif
#ifdef LOG_NOWAIT
PyModule_AddIntConstant(m, "LOG_NOWAIT", LOG_NOWAIT);
#endif
......@@ -331,5 +334,10 @@ PyInit_syslog(void)
PyModule_AddIntConstant(m, "LOG_CRON", LOG_CRON);
PyModule_AddIntConstant(m, "LOG_UUCP", LOG_UUCP);
PyModule_AddIntConstant(m, "LOG_NEWS", LOG_NEWS);
#ifdef LOG_AUTHPRIV
PyModule_AddIntConstant(m, "LOG_AUTHPRIV", LOG_AUTHPRIV);
#endif
return m;
}
......@@ -16,53 +16,16 @@
/* Special free list
Since some Python programs can spend much of their time allocating
and deallocating floats, these operations should be very fast.
Therefore we use a dedicated allocation scheme with a much lower
overhead (in space and time) than straight malloc(): a simple
dedicated free list, filled when necessary with memory from malloc().
block_list is a singly-linked list of all PyFloatBlocks ever allocated,
linked via their next members. PyFloatBlocks are never returned to the
system before shutdown (PyFloat_Fini).
free_list is a singly-linked list of available PyFloatObjects, linked
via abuse of their ob_type members.
*/
#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */
#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */
#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))
struct _floatblock {
struct _floatblock *next;
PyFloatObject objects[N_FLOATOBJECTS];
};
typedef struct _floatblock PyFloatBlock;
static PyFloatBlock *block_list = NULL;
#ifndef PyFloat_MAXFREELIST
#define PyFloat_MAXFREELIST 100
#endif
static int numfree = 0;
static PyFloatObject *free_list = NULL;
static PyFloatObject *
fill_free_list(void)
{
PyFloatObject *p, *q;
/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
if (p == NULL)
return (PyFloatObject *) PyErr_NoMemory();
((PyFloatBlock *)p)->next = block_list;
block_list = (PyFloatBlock *)p;
p = &((PyFloatBlock *)p)->objects[0];
q = p + N_FLOATOBJECTS;
while (--q > p)
Py_TYPE(q) = (struct _typeobject *)(q-1);
Py_TYPE(q) = NULL;
return p + N_FLOATOBJECTS - 1;
}
double
PyFloat_GetMax(void)
{
......@@ -151,14 +114,16 @@ PyFloat_GetInfo(void)
PyObject *
PyFloat_FromDouble(double fval)
{
register PyFloatObject *op;
if (free_list == NULL) {
if ((free_list = fill_free_list()) == NULL)
return NULL;
register PyFloatObject *op = free_list;
if (op != NULL) {
free_list = (PyFloatObject *) Py_TYPE(op);
numfree--;
} else {
op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
if (!op)
return PyErr_NoMemory();
}
/* Inline PyObject_New */
op = free_list;
free_list = (PyFloatObject *)Py_TYPE(op);
PyObject_INIT(op, &PyFloat_Type);
op->ob_fval = fval;
return (PyObject *) op;
......@@ -217,6 +182,11 @@ static void
float_dealloc(PyFloatObject *op)
{
if (PyFloat_CheckExact(op)) {
if (numfree >= PyFloat_MAXFREELIST) {
PyObject_FREE(op);
return;
}
numfree++;
Py_TYPE(op) = (struct _typeobject *)free_list;
free_list = op;
}
......@@ -1932,96 +1902,22 @@ _PyFloat_Init(void)
int
PyFloat_ClearFreeList(void)
{
PyFloatObject *p;
PyFloatBlock *list, *next;
int i;
int u; /* remaining unfreed floats per block */
int freelist_size = 0;
list = block_list;
block_list = NULL;
free_list = NULL;
while (list != NULL) {
u = 0;
for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS;
i++, p++) {
if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
u++;
}
next = list->next;
if (u) {
list->next = block_list;
block_list = list;
for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS;
i++, p++) {
if (!PyFloat_CheckExact(p) ||
Py_REFCNT(p) == 0) {
Py_TYPE(p) = (struct _typeobject *)
free_list;
free_list = p;
}
}
}
else {
PyMem_FREE(list);
}
freelist_size += u;
list = next;
PyFloatObject *f = free_list, *next;
int i = numfree;
while (f) {
next = (PyFloatObject*) Py_TYPE(f);
PyObject_FREE(f);
f = next;
}
return freelist_size;
free_list = NULL;
numfree = 0;
return i;
}
void
PyFloat_Fini(void)
{
PyFloatObject *p;
PyFloatBlock *list;
int i;
int u; /* total unfreed floats per block */
u = PyFloat_ClearFreeList();
if (!Py_VerboseFlag)
return;
fprintf(stderr, "# cleanup floats");
if (!u) {
fprintf(stderr, "\n");
}
else {
fprintf(stderr,
": %d unfreed float%s\n",
u, u == 1 ? "" : "s");
}
if (Py_VerboseFlag > 1) {
list = block_list;
while (list != NULL) {
for (i = 0, p = &list->objects[0];
i < N_FLOATOBJECTS;
i++, p++) {
if (PyFloat_CheckExact(p) &&
Py_REFCNT(p) != 0) {
char *buf = PyOS_double_to_string(
PyFloat_AS_DOUBLE(p), 'r',
0, 0, NULL);
if (buf) {
/* XXX(twouters) cast
refcount to long
until %zd is
universally
available
*/
fprintf(stderr,
"# <float at %p, refcnt=%ld, val=%s>\n",
p, (long)Py_REFCNT(p), buf);
PyMem_Free(buf);
}
}
}
list = list->next;
}
}
(void)PyFloat_ClearFreeList();
}
/*----------------------------------------------------------------------------
......
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