Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60849,60852-60854,60856-60859,60861-60870,60874-60875,60880-60881,60886,60888-60890,60892,60894-60898,60900-60931,60933-60958 via svnmerge from

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

........
  r60901 | eric.smith | 2008-02-19 14:21:56 +0100 (Tue, 19 Feb 2008) | 1 line

  Added PEP 3101.
........
  r60907 | georg.brandl | 2008-02-20 20:12:36 +0100 (Wed, 20 Feb 2008) | 2 lines

  Fixes contributed by Ori Avtalion.
........
  r60909 | eric.smith | 2008-02-21 00:34:22 +0100 (Thu, 21 Feb 2008) | 1 line

  Trim leading zeros from a floating point exponent, per C99.  See issue 1600.  As far as I know, this only affects Windows.  Add float type 'n' to PyOS_ascii_formatd (see PEP 3101 for 'n' description).
........
  r60910 | eric.smith | 2008-02-21 00:39:28 +0100 (Thu, 21 Feb 2008) | 1 line

  Now that PyOS_ascii_formatd supports the 'n' format, simplify the float formatting code to just call it.
........
  r60918 | andrew.kuchling | 2008-02-21 15:23:38 +0100 (Thu, 21 Feb 2008) | 2 lines

  Close manifest file.
  This change doesn't make any difference to CPython, but is a necessary fix for Jython.
........
  r60921 | guido.van.rossum | 2008-02-21 18:46:16 +0100 (Thu, 21 Feb 2008) | 2 lines

  Remove news about float repr() -- issue 1580 is still in limbo.
........
  r60923 | guido.van.rossum | 2008-02-21 19:18:37 +0100 (Thu, 21 Feb 2008) | 5 lines

  Removed uses of dict.has_key() from distutils, and uses of
  callable() from copy_reg.py, so the interpreter now starts up
  without warnings when '-3' is given.  More work like this needs to
  be done in the rest of the stdlib.
........
  r60924 | thomas.heller | 2008-02-21 19:28:48 +0100 (Thu, 21 Feb 2008) | 4 lines

  configure.ac: Remove the configure check for _Bool, it is already done in the
  top-level Python configure script.
  configure, fficonfig.h.in: regenerated.
........
  r60925 | thomas.heller | 2008-02-21 19:52:20 +0100 (Thu, 21 Feb 2008) | 3 lines

  Replace 'has_key()' with 'in'.
  Replace 'raise Error, stuff' with 'raise Error(stuff)'.
........
  r60927 | raymond.hettinger | 2008-02-21 20:24:53 +0100 (Thu, 21 Feb 2008) | 1 line

  Update more instances of has_key().
........
  r60928 | guido.van.rossum | 2008-02-21 20:46:35 +0100 (Thu, 21 Feb 2008) | 3 lines

  Fix a few typos and layout glitches (more work is needed).
  Move 2.5 news to Misc/HISTORY.
........
  r60936 | georg.brandl | 2008-02-21 21:33:38 +0100 (Thu, 21 Feb 2008) | 2 lines

  #2079: typo in userdict docs.
........
  r60938 | georg.brandl | 2008-02-21 21:38:13 +0100 (Thu, 21 Feb 2008) | 2 lines

  Part of #2154: minimal syntax fixes in doc example snippets.
........
  r60942 | raymond.hettinger | 2008-02-22 04:16:42 +0100 (Fri, 22 Feb 2008) | 1 line

  First draft for itertools.product().  Docs and other updates forthcoming.
........
  r60955 | nick.coghlan | 2008-02-22 11:54:06 +0100 (Fri, 22 Feb 2008) | 1 line

  Try to make command line error messages from runpy easier to understand (and suppress traceback cruft from the implicitly invoked runpy machinery)
........
  r60956 | georg.brandl | 2008-02-22 13:31:45 +0100 (Fri, 22 Feb 2008) | 2 lines

  A lot more typo fixes by Ori Avtalion.
........
  r60957 | georg.brandl | 2008-02-22 13:56:34 +0100 (Fri, 22 Feb 2008) | 2 lines

  Don't reference pyshell.
........
  r60958 | georg.brandl | 2008-02-22 13:57:05 +0100 (Fri, 22 Feb 2008) | 2 lines

  Another fix.
........
This commit is contained in:
Christian Heimes 2008-02-22 16:37:40 +00:00
parent 86bc17944f
commit c3f30c4337
41 changed files with 5703 additions and 3333 deletions

View File

@ -190,7 +190,7 @@ All integers are implemented as "long" integer objects of arbitrary size.
.. cfunction:: void* PyLong_AsVoidPtr(PyObject *pylong)
Convert a Python integer *pylong* to a C :ctype:`void` pointer. If *pylong*
cannot be converted, an :exc:`OverflowError` will be raised. This is only
assured to produce a usable :ctype:`void` pointer for values created with
:cfunc:`PyLong_FromVoidPtr`.
Convert a Python integer *pylong* to a C :ctype:`void` pointer.
If *pylong* cannot be converted, an :exc:`OverflowError` will be raised. This
is only assured to produce a usable :ctype:`void` pointer for values created
with :cfunc:`PyLong_FromVoidPtr`.

View File

@ -8,7 +8,7 @@ Buffer Protocol
.. cfunction:: int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)
Returns a pointer to a read-only memory location useable as character- based
Returns a pointer to a read-only memory location usable as character-based
input. The *obj* argument must support the single-segment character buffer
interface. On success, returns ``0``, sets *buffer* to the memory location and
*buffer_len* to the buffer length. Returns ``-1`` and sets a :exc:`TypeError`

View File

@ -560,7 +560,7 @@ The following three fields only exist if the
The :attr:`tp_traverse` pointer is used by the garbage collector to detect
reference cycles. A typical implementation of a :attr:`tp_traverse` function
simply calls :cfunc:`Py_VISIT` on each of the instance's members that are Python
objects. For exampe, this is function :cfunc:`local_traverse` from the
objects. For example, this is function :cfunc:`local_traverse` from the
:mod:`thread` extension module::
static int

View File

@ -195,7 +195,7 @@ Distutils configuration files. Various options and sections in the
| | or --- & :option:`maintainer` and |
| | :option:`maintainer_email` |
+------------------------------------------+----------------------------------------------+
| Copyright | :option:`licence` |
| Copyright | :option:`license` |
+------------------------------------------+----------------------------------------------+
| Url | :option:`url` |
+------------------------------------------+----------------------------------------------+

View File

@ -53,13 +53,13 @@ the web interface.
The .pypirc file
================
The format of the :file:`.pypirc` file is formated as follows::
The format of the :file:`.pypirc` file is as follows::
[server-login]
repository: <repository-url>
username: <username>
password: <password>
*repository* can be ommitted and defaults to ``http://www.python.org/pypi``.
*repository* can be omitted and defaults to ``http://www.python.org/pypi``.

View File

@ -185,7 +185,7 @@ 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(...
setup(...,
ext_package='pkg',
ext_modules=[Extension('foo', ['foo.c']),
Extension('subpkg.bar', ['bar.c'])],
@ -214,7 +214,7 @@ extension.
This warning notwithstanding, options to SWIG can be currently passed like
this::
setup(...
setup(...,
ext_modules=[Extension('_foo', ['foo.i'],
swig_opts=['-modern', '-I../include'])],
py_modules=['foo'],
@ -443,7 +443,7 @@ 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(...
setup(...,
scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val']
)
@ -499,7 +499,7 @@ anything which doesn't fit in the previous categories.
:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the
following way::
setup(...
setup(...,
data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']),
('config', ['cfg/data.cfg']),
('/etc/init.d', ['init-script'])]
@ -611,7 +611,7 @@ information is sometimes used to indicate sub-releases. These are
:option:`classifiers` are specified in a python list::
setup(...
setup(...,
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',

View File

@ -276,7 +276,7 @@ language, but it boils down to three conditions:
product in any way.
* If something goes wrong, you can't sue for damages. Practically all software
licences contain this condition.
licenses contain this condition.
Notice that you don't have to provide source code for anything that contains
Python or is built with it. Also, the Python interpreter and accompanying

View File

@ -81,7 +81,7 @@ from module import name1, name2
This is a "don't" which is much weaker then the previous "don't"s but is still
something you should not do if you don't have good reasons to do that. The
reason it is usually bad idea is because you suddenly have an object which lives
in two seperate namespaces. When the binding in one namespace changes, the
in two separate namespaces. When the binding in one namespace changes, the
binding in the other will not, so there will be a discrepancy between them. This
happens when, for example, one module is reloaded, or changes the definition of
a function at runtime.

View File

@ -892,7 +892,7 @@ returns them in a tuple::
itertools.izip(['a', 'b', 'c'], (1, 2, 3)) =>
('a', 1), ('b', 2), ('c', 3)
It's similiar to the built-in :func:`zip` function, but doesn't construct an
It's similar to the built-in :func:`zip` function, but doesn't construct an
in-memory list and exhaust all the input iterators before returning; instead
tuples are constructed and returned only if they're requested. (The technical
term for this behaviour is `lazy evaluation

View File

@ -354,7 +354,7 @@ thing to do - give it a nice long timeout (say a minute) unless you have good
reason to do otherwise.
In return, you will get three lists. They have the sockets that are actually
readable, writable and in error. Each of these lists is a subset (possbily
readable, writable and in error. Each of these lists is a subset (possibly
empty) of the corresponding list you passed in. And if you put a socket in more
than one input list, it will only be (at most) in one output list.
@ -368,7 +368,7 @@ just means outbound network buffer space is available.)
If you have a "server" socket, put it in the potential_readers list. If it comes
out in the readable list, your ``accept`` will (almost certainly) work. If you
have created a new socket to ``connect`` to someone else, put it in the
ptoential_writers list. If it shows up in the writable list, you have a decent
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

View File

@ -1018,7 +1018,7 @@ particular, the following variants typically exist:
+-----------------+--------------------------------+--------------------------------+
| iso8859_3 | iso-8859-3, latin3, L3 | Esperanto, Maltese |
+-----------------+--------------------------------+--------------------------------+
| iso8859_4 | iso-8859-4, latin4, L4 | Baltic languagues |
| iso8859_4 | iso-8859-4, latin4, L4 | Baltic languages |
+-----------------+--------------------------------+--------------------------------+
| iso8859_5 | iso-8859-5, cyrillic | Bulgarian, Byelorussian, |
| | | Macedonian, Russian, Serbian |

View File

@ -452,7 +452,7 @@ they add the ability to access fields by name instead of position index.
.. function:: namedtuple(typename, fieldnames, [verbose])
Returns a new tuple subclass named *typename*. The new subclass is used to
create tuple-like objects that have fields accessable by attribute lookup as
create tuple-like objects that have fields accessible by attribute lookup as
well as being indexable and iterable. Instances of the subclass also have a
helpful docstring (with typename and fieldnames) and a helpful :meth:`__repr__`
method which lists the tuple contents in a ``name=value`` format.
@ -516,7 +516,7 @@ Example::
>>> x, y = p # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y # fields also accessable by name
>>> p.x + p.y # fields also accessible by name
33
>>> p # readable __repr__ with a name=value style
Point(x=11, y=22)
@ -708,7 +708,7 @@ consult the sources for information about the methods which need to be provided
in that case.
:class:`UserString` objects
-------------------------
---------------------------
The class, :class:`UserString` acts as a wrapper around string objects.
The need for this class has been partially supplanted by the ability to

View File

@ -1557,7 +1557,7 @@ of significant places in the coefficient. For example, expressing
original's two-place significance.
If an application does not care about tracking significance, it is easy to
remove the exponent and trailing zeroes, losing signficance, but keeping the
remove the exponent and trailing zeroes, losing significance, but keeping the
value unchanged::
>>> def remove_exponent(d):

View File

@ -41,7 +41,7 @@ can include messages from third-party modules.
It is, of course, possible to log messages with different verbosity levels or to
different destinations. Support for writing log messages to files, HTTP
GET/POST locations, email via SMTP, generic sockets, or OS-specific logging
mechnisms are all supported by the standard module. You can also create your
mechanisms are all supported by the standard module. You can also create your
own log destination class if you have special requirements not met by any of the
built-in classes.
@ -265,7 +265,7 @@ destination. Logger objects can add zero or more handler objects to themselves
with an :func:`addHandler` method. As an example scenario, an application may
want to send all log messages to a log file, all log messages of error or higher
to stdout, and all messages of critical to an email address. This scenario
requires three individual handlers where each hander is responsible for sending
requires three individual handlers where each handler is responsible for sending
messages of a specific severity to a specific location.
The standard library includes quite a few handler types; this tutorial uses only

View File

@ -432,7 +432,7 @@ the original. In the interest of compatibility, :class:`mbox` implements the
original format, which is sometimes referred to as :dfn:`mboxo`. This means that
the :mailheader:`Content-Length` header, if present, is ignored and that any
occurrences of "From " at the beginning of a line in a message body are
transformed to ">From " when storing the message, although occurences of ">From
transformed to ">From " when storing the message, although occurrences of ">From
" are not transformed to "From " when reading the message.
Some :class:`Mailbox` methods implemented by :class:`mbox` deserve special
@ -580,7 +580,7 @@ remarks:
.. method:: MH.close()
:class:`MH` instances do not keep any open files, so this method is equivelant
:class:`MH` instances do not keep any open files, so this method is equivalent
to :meth:`unlock`.

View File

@ -1629,7 +1629,7 @@ arguments::
value.append(arg)
del rargs[0]
setattr(parser.values, option.dest, value)
setattr(parser.values, option.dest, value)
[...]
parser.add_option("-c", "--callback",

View File

@ -237,7 +237,7 @@ Unix Platforms
version)`` which default to the given parameters in case the lookup fails.
Note that this function has intimate knowledge of how different libc versions
add symbols to the executable is probably only useable for executables compiled
add symbols to the executable is probably only usable for executables compiled
using :program:`gcc`.
The file is read and scanned in chunks of *chunksize* bytes.

View File

@ -513,7 +513,7 @@ The :class:`Stats` Class
non-parenthesized number repeats the cumulative time spent in the function
at the right.
* With :mod:`cProfile`, each caller is preceeded by three numbers: the number of
* With :mod:`cProfile`, each caller is preceded by three numbers: the number of
times this specific call was made, and the total and cumulative times spent in
the current function while it was invoked by this specific caller.

View File

@ -68,6 +68,17 @@ Bookkeeping functions:
the time :func:`setstate` was called.
.. function:: jumpahead(n)
Change the internal state to one different from and likely far away from the
current state. *n* is a non-negative integer which is used to scramble the
current state vector. This is most useful in multi-threaded programs, in
conjunction with multiple instances of the :class:`Random` class:
:meth:`setstate` or :meth:`seed` can be used to force all instances into the
same internal state, and then :meth:`jumpahead` can be used to force the
instances' states far apart.
.. function:: getrandbits(k)
Returns a python integer with *k* random bits. This method is supplied with

View File

@ -1089,7 +1089,7 @@ into a list with each nonempty line having its own entry::
'Heather Albrecht 548.326.4584 919 Park Place']
Finally, split each entry into a list with first name, last name, telephone
number, and address. We use the ``maxsplit`` paramater of :func:`split`
number, and address. We use the ``maxsplit`` parameter of :func:`split`
because the address has spaces, our splitting pattern, in it::
>>> [re.split(":? ", entry, 3) for entry in entries]
@ -1099,7 +1099,7 @@ because the address has spaces, our splitting pattern, in it::
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
The ``:?`` pattern matches the colon after the last name, so that it does not
occur in the result list. With a ``maxsplit`` of ``4``, we could seperate the
occur in the result list. With a ``maxsplit`` of ``4``, we could separate the
house number from the street name::
>>> [re.split(":? ", entry, 4) for entry in entries]
@ -1131,7 +1131,7 @@ in each word of a sentence except for the first and last characters::
Finding all Adverbs
^^^^^^^^^^^^^^^^^^^
:func:`findall` matches *all* occurences of a pattern, not just the first
:func:`findall` matches *all* occurrences of a pattern, not just the first
one as :func:`search` does. For example, if one was a writer and wanted to
find all of the adverbs in some text, he or she might use :func:`findall` in
the following manner::

View File

@ -886,5 +886,5 @@ the interface::
# receive a package
print s.recvfrom(65565)
# disabled promiscous mode
# disabled promiscuous mode
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

View File

@ -18,7 +18,7 @@ The primary entry point is a :term:`generator`:
.. function:: generate_tokens(readline)
The :func:`generate_tokens` generator requires one argment, *readline*, which
The :func:`generate_tokens` generator requires one argument, *readline*, which
must be a callable object which provides the same interface as the
:meth:`readline` method of built-in file objects (see section
:ref:`bltin-file-objects`). Each call to the function should return one line of

View File

@ -61,7 +61,7 @@ support weak references but can add support through subclassing::
class Dict(dict):
pass
obj = Dict(red=1, green=2, blue=3) # this object is weak referencable
obj = Dict(red=1, green=2, blue=3) # this object is weak referenceable
Extension types can easily be made to support weak references; see
:ref:`weakref-support`.

View File

@ -421,7 +421,7 @@ TreeBuilder Objects
.. method:: TreeBuilder.close()
Flushes the parser buffers, and returns the toplevel documen element. Returns an
Flushes the parser buffers, and returns the toplevel document element. Returns an
Element instance.

View File

@ -589,7 +589,7 @@ implementation details.
.. rubric:: Footnotes
.. [#] The exception is propogated to the invocation stack only if there is no
.. [#] The exception is propagated to the invocation stack only if there is no
:keyword:`finally` clause that negates the exception.
.. [#] Currently, control "flows off the end" except in the case of an exception or the

View File

@ -380,7 +380,7 @@ generator function:
generator, or raises :exc:`StopIteration` if the generator exits without
yielding another value. When :meth:`send` is called to start the generator,
it must be called with :const:`None` as the argument, because there is no
:keyword:`yield` expression that could receieve the value.
:keyword:`yield` expression that could receive the value.
.. method:: generator.throw(type[, value[, traceback]])
@ -652,7 +652,7 @@ there were no excess keyword arguments.
If the syntax ``*expression`` appears in the function call, ``expression`` must
evaluate to a sequence. Elements from this sequence are treated as if they were
additional positional arguments; if there are postional arguments *x1*,...,*xN*
additional positional arguments; if there are positional arguments *x1*,...,*xN*
, and ``expression`` evaluates to a sequence *y1*,...,*yM*, this is equivalent
to a call with M+N positional arguments *x1*,...,*xN*,*y1*,...,*yM*.

View File

@ -17,7 +17,7 @@ write a Python extension module, and the :ref:`c-api-index` describes the
interfaces available to C/C++ programmers in detail.
.. toctree::
:maxdepth: 3
:maxdepth: 2
introduction.rst
lexical_analysis.rst

View File

@ -269,7 +269,7 @@ applications include caching objects that are expensive to create::
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
File "<pyshell#108>", line 1, in -toplevel-
File "<stdin>", line 1, in <module>
d['primary'] # entry was automatically removed
File "C:/python30/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()

View File

@ -560,7 +560,7 @@ doing ``isinstance(obj, Number)``.
Numbers are further divided into :class:`Exact` and :class:`Inexact`.
Exact numbers can represent values precisely and operations never
round off the results or introduce tiny errors that may break the
communtativity and associativity properties; inexact numbers may
commutativity and associativity properties; inexact numbers may
perform such rounding or introduce small errors. Integers, long
integers, and rational numbers are exact, while floating-point
and complex numbers are inexact.
@ -707,8 +707,10 @@ Here are all of the changes that Python 2.6 makes to the core Python language.
Other functions in the :mod:`math` module, :func:`isinf` and
:func:`isnan`, return true if their floating-point argument is
infinite or Not A Number.
infinite or Not A Number.
.. Patch 1640
The ``math.copysign(x, y)`` function
copies the sign bit of an IEEE 754 number, returning the absolute
value of *x* combined with the sign bit of *y*. For example,
@ -1078,7 +1080,7 @@ complete list of changes, or look through the CVS logs for all the details.
* Integrating signal handling with GUI handling event loops
like those used by Tkinter or GTk+ has long been a problem; most
software ends up polling, waking up every fraction of a second. Thi
software ends up polling, waking up every fraction of a second.
The :mod:`signal` module can now make this more efficient.
Calling ``signal.set_wakeup_fd(fd)`` sets a file descriptor
to be used; when a signal is received, a byte is written to that
@ -1293,7 +1295,8 @@ complete list of changes, or look through the CVS logs for all the details.
z.extractall()
(Contributed by Alan McIntyre.)
.. % Patch 467924
.. Patch 467924
.. ======================================================================
.. whole new modules get described in subsections here
@ -1392,7 +1395,7 @@ Changes to Python's build process and to the C API include:
.. Issue 1534
* Python's C API now includes two functions for case-insensitive string
comparisions, ``PyOS_stricmp(char*, char*)``
comparisons, ``PyOS_stricmp(char*, char*)``
and ``PyOS_strnicmp(char*, char*, Py_ssize_t)``.
(Contributed by Christian Heimes.)

View File

@ -147,11 +147,11 @@ class CCompiler:
# discovered at run-time, since there are many different ways to do
# basically the same things with Unix C compilers.
for key, value in kwargs.items():
for key in kwargs:
if key not in self.executables:
raise ValueError("unknown executable '%s' for class %s" % \
raise ValueError("unknown executable '%s' for class %s" %
(key, self.__class__.__name__))
self.set_executable(key, value)
self.set_executable(key, kwargs[key])
def set_executable(self, key, value):
if isinstance(value, str):

View File

@ -357,6 +357,7 @@ class sdist (Command):
if line[-1] == '\n':
line = line[0:-1]
self.filelist.append(line)
manifest.close()
def make_release_tree(self, base_dir, files):
"""Create the directory tree that will become the source

View File

@ -89,6 +89,9 @@ def _get_module_details(mod_name):
# 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, set_argv0=True):
"""Runs the designated module in the __main__ namespace
@ -96,7 +99,20 @@ def _run_module_as_main(mod_name, set_argv0=True):
__file__
__loader__
"""
loader, code, fname = _get_module_details(mod_name)
try:
loader, code, fname = _get_module_details(mod_name)
except ImportError as exc:
# Try to provide a good error message
# for directories, zip files and the -m switch
if set_argv0:
# For -m switch, just disply 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__
if set_argv0:

View File

@ -5,6 +5,7 @@ from weakref import proxy
import sys
import operator
import random
from functools import reduce
maxsize = test_support.MAX_Py_ssize_t
minsize = -maxsize-1
@ -261,6 +262,28 @@ class TestBasicOps(unittest.TestCase):
ids = list(map(id, list(izip_longest('abc', 'def'))))
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
def test_product(self):
for args, result in [
([], []), # zero iterables ??? is this correct
(['ab'], [('a',), ('b',)]), # one iterable
([range(2), range(3)], [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]), # two iterables
([range(0), range(2), range(3)], []), # first iterable with zero length
([range(2), range(0), range(3)], []), # middle iterable with zero length
([range(2), range(3), range(0)], []), # last iterable with zero length
]:
self.assertEqual(list(product(*args)), result)
self.assertEqual(len(list(product(*[range(7)]*6))), 7**6)
self.assertRaises(TypeError, product, range(6), None)
argtypes = ['', 'abc', '', range(0), range(4), dict(a=1, b=2, c=3),
set('abcdefg'), range(11), tuple(range(13))]
for i in range(100):
args = [random.choice(argtypes) for j in range(random.randrange(5))]
n = reduce(operator.mul, map(len, args), 1) if args else 0
self.assertEqual(len(list(product(*args))), n)
args = map(iter, args)
self.assertEqual(len(list(product(*args))), n)
def test_repeat(self):
self.assertEqual(lzip(range(3),repeat('a')),
[(0, 'a'), (1, 'a'), (2, 'a')])
@ -636,6 +659,12 @@ class TestVariousIteratorArgs(unittest.TestCase):
self.assertRaises(TypeError, chain, N(s))
self.assertRaises(ZeroDivisionError, list, chain(E(s)))
def test_product(self):
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
self.assertRaises(TypeError, product, X(s))
self.assertRaises(TypeError, product, N(s))
self.assertRaises(ZeroDivisionError, product, E(s))
def test_cycle(self):
for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)):
for g in (G, I, Ig, S, L, R):

View File

@ -89,6 +89,29 @@ class TypesTests(unittest.TestCase):
if float(1) == 1.0 and float(-1) == -1.0 and float(0) == 0.0: pass
else: self.fail('float() does not work properly')
def test_float_to_string(self):
def test(f, result):
self.assertEqual(f.__format__('e'), result)
self.assertEqual('%e' % f, result)
# test all 2 digit exponents, both with __format__ and with
# '%' formatting
for i in range(-99, 100):
test(float('1.5e'+str(i)), '1.500000e{0:+03d}'.format(i))
# test some 3 digit exponents
self.assertEqual(1.5e100.__format__('e'), '1.500000e+100')
self.assertEqual('%e' % 1.5e100, '1.500000e+100')
self.assertEqual(1.5e101.__format__('e'), '1.500000e+101')
self.assertEqual('%e' % 1.5e101, '1.500000e+101')
self.assertEqual(1.5e-100.__format__('e'), '1.500000e-100')
self.assertEqual('%e' % 1.5e-100, '1.500000e-100')
self.assertEqual(1.5e-101.__format__('e'), '1.500000e-101')
self.assertEqual('%e' % 1.5e-101, '1.500000e-101')
def test_normal_integers(self):
# Ensure the first 256 integers are shared
a = 256
@ -416,16 +439,17 @@ class TypesTests(unittest.TestCase):
test(-1.0, ' f', '-1.000000')
test( 1.0, '+f', '+1.000000')
test(-1.0, '+f', '-1.000000')
test(1.1234e90, 'f', '1.1234e+90')
test(1.1234e90, 'F', '1.1234e+90')
test(1.1234e200, 'f', '1.1234e+200')
test(1.1234e200, 'F', '1.1234e+200')
# temporarily removed. see issue 1600
# test( 1.0, 'e', '1.000000e+00')
# test(-1.0, 'e', '-1.000000e+00')
# test( 1.0, 'E', '1.000000E+00')
# test(-1.0, 'E', '-1.000000E+00')
# test(1.1234e20, 'e', '1.123400e+20')
# test(1.1234e20, 'E', '1.123400E+20')
test( 1.0, 'e', '1.000000e+00')
test(-1.0, 'e', '-1.000000e+00')
test( 1.0, 'E', '1.000000E+00')
test(-1.0, 'E', '-1.000000E+00')
test(1.1234e20, 'e', '1.123400e+20')
test(1.1234e20, 'E', '1.123400E+20')
# % formatting
test(-1.0, '%', '-100.000000%')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -106,17 +106,6 @@ if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
fi
AC_SUBST(HAVE_LONG_DOUBLE)
AC_MSG_CHECKING(for _Bool support)
have_c99_bool=no
AC_TRY_COMPILE([], [_Bool x; x = (_Bool)0;], [
AC_DEFINE(HAVE_C99_BOOL, 1, [Define this if you have the type _Bool.])
have_c99_bool=yes
])
AC_MSG_RESULT($have_c99_bool)
if test "$have_c99_bool" = yes ; then
AC_CHECK_SIZEOF(_Bool, 1)
fi
AC_C_BIGENDIAN
AH_VERBATIM([WORDS_BIGENDIAN],
[

View File

@ -28,9 +28,6 @@
*/
#undef HAVE_AS_SPARC_UA_PCREL
/* Define this if you have the type _Bool. */
#undef HAVE_C99_BOOL
/* Define if __attribute__((visibility("hidden"))) is supported. */
#undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
@ -100,18 +97,15 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of a `double', as computed by sizeof. */
/* The size of `double', as computed by sizeof. */
#undef SIZEOF_DOUBLE
/* The size of a `long double', as computed by sizeof. */
/* The size of `long double', as computed by sizeof. */
#undef SIZEOF_LONG_DOUBLE
/* The size of a `_Bool', as computed by sizeof. */
#undef SIZEOF__BOOL
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */

View File

@ -1711,6 +1711,216 @@ static PyTypeObject chain_type = {
};
/* product object ************************************************************/
typedef struct {
PyObject_HEAD
PyObject *pools; /* tuple of pool tuples */
Py_ssize_t *maxvec;
Py_ssize_t *indices;
PyObject *result;
int stopped;
} productobject;
static PyTypeObject product_type;
static PyObject *
product_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
productobject *lz;
Py_ssize_t npools;
PyObject *pools = NULL;
Py_ssize_t *maxvec = NULL;
Py_ssize_t *indices = NULL;
Py_ssize_t i;
if (type == &product_type && !_PyArg_NoKeywords("product()", kwds))
return NULL;
assert(PyTuple_Check(args));
npools = PyTuple_GET_SIZE(args);
maxvec = PyMem_Malloc(npools * sizeof(Py_ssize_t));
indices = PyMem_Malloc(npools * sizeof(Py_ssize_t));
if (maxvec == NULL || indices == NULL) {
PyErr_NoMemory();
goto error;
}
pools = PyTuple_New(npools);
if (pools == NULL)
goto error;
for (i=0; i < npools; ++i) {
PyObject *item = PyTuple_GET_ITEM(args, i);
PyObject *pool = PySequence_Tuple(item);
if (pool == NULL)
goto error;
PyTuple_SET_ITEM(pools, i, pool);
maxvec[i] = PyTuple_GET_SIZE(pool);
indices[i] = 0;
}
/* create productobject structure */
lz = (productobject *)type->tp_alloc(type, 0);
if (lz == NULL) {
Py_DECREF(pools);
return NULL;
}
lz->pools = pools;
lz->maxvec = maxvec;
lz->indices = indices;
lz->result = NULL;
lz->stopped = 0;
return (PyObject *)lz;
error:
if (maxvec != NULL)
PyMem_Free(maxvec);
if (indices != NULL)
PyMem_Free(indices);
Py_XDECREF(pools);
return NULL;
}
static void
product_dealloc(productobject *lz)
{
PyObject_GC_UnTrack(lz);
Py_XDECREF(lz->pools);
Py_XDECREF(lz->result);
PyMem_Free(lz->maxvec);
PyMem_Free(lz->indices);
Py_TYPE(lz)->tp_free(lz);
}
static int
product_traverse(productobject *lz, visitproc visit, void *arg)
{
Py_VISIT(lz->pools);
Py_VISIT(lz->result);
return 0;
}
static PyObject *
product_next(productobject *lz)
{
PyObject *pool;
PyObject *elem;
PyObject *tuple_result;
PyObject *pools = lz->pools;
PyObject *result = lz->result;
Py_ssize_t npools = PyTuple_GET_SIZE(pools);
Py_ssize_t i;
if (lz->stopped)
return NULL;
if (result == NULL) {
if (npools == 0)
goto empty;
result = PyList_New(npools);
if (result == NULL)
goto empty;
lz->result = result;
for (i=0; i < npools; i++) {
pool = PyTuple_GET_ITEM(pools, i);
if (PyTuple_GET_SIZE(pool) == 0)
goto empty;
elem = PyTuple_GET_ITEM(pool, 0);
Py_INCREF(elem);
PyList_SET_ITEM(result, i, elem);
}
} else {
Py_ssize_t *indices = lz->indices;
Py_ssize_t *maxvec = lz->maxvec;
for (i=npools-1 ; i >= 0 ; i--) {
pool = PyTuple_GET_ITEM(pools, i);
indices[i]++;
if (indices[i] == maxvec[i]) {
indices[i] = 0;
elem = PyTuple_GET_ITEM(pool, 0);
Py_INCREF(elem);
PyList_SetItem(result, i, elem);
} else {
elem = PyTuple_GET_ITEM(pool, indices[i]);
Py_INCREF(elem);
PyList_SetItem(result, i, elem);
break;
}
}
if (i < 0)
return NULL;
}
tuple_result = PySequence_Tuple(result);
if (tuple_result == NULL)
lz->stopped = 1;
return tuple_result;
empty:
lz->stopped = 1;
return NULL;
}
PyDoc_STRVAR(product_doc,
"product(*iterables) --> product object\n\
\n\
Cartesian product of input interables. Equivalent to nested for-loops.\n\n\
For example, product(A, B) returns the same as: ((x,y) for x in A for y in B).\n\
The leftmost iterators are in the outermost for-loop, so the output tuples\n\
cycle in a manner similar to an odometer (with the rightmost element changing\n\
on every iteration).\n\n\
product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\
product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ...");
static PyTypeObject product_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"itertools.product", /* tp_name */
sizeof(productobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
(destructor)product_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
product_doc, /* tp_doc */
(traverseproc)product_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)product_next, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* 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 */
product_new, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
/* ifilter object ************************************************************/
typedef struct {
@ -2748,7 +2958,8 @@ inititertools(void)
&ifilterfalse_type,
&count_type,
&izip_type,
&iziplongest_type,
&iziplongest_type,
&product_type,
&repeat_type,
&groupby_type,
NULL

View File

@ -130,16 +130,16 @@ parse_internal_render_format_spec(PyObject *format_spec,
}
else if (end-ptr >= 1 && is_alignment_token(ptr[0])) {
format->align = ptr[0];
ptr++;
++ptr;
}
/* Parse the various sign options */
if (end-ptr >= 1 && is_sign_element(ptr[0])) {
format->sign = ptr[0];
ptr++;
++ptr;
#if ALLOW_PARENS_FOR_SIGN
if (end-ptr >= 1 && ptr[0] == ')') {
ptr++;
++ptr;
}
#endif
}
@ -150,7 +150,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
if (format->align == '\0') {
format->align = '=';
}
ptr++;
++ptr;
}
/* XXX add error checking */
@ -165,7 +165,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
/* Parse field precision */
if (end-ptr && ptr[0] == '.') {
ptr++;
++ptr;
/* XXX add error checking */
specified_width = get_integer(&ptr, end, &format->precision);
@ -189,7 +189,7 @@ parse_internal_render_format_spec(PyObject *format_spec,
if (end-ptr == 1) {
format->type = ptr[0];
ptr++;
++ptr;
}
return 1;
@ -570,7 +570,7 @@ format_int_or_long_internal(PyObject *value, const InternalFormatSpec *format,
/* if X, convert to uppercase */
if (format->type == 'X') {
Py_ssize_t t;
for (t = 0; t < n_digits; t++)
for (t = 0; t < n_digits; ++t)
p[t + n_leading_chars] = STRINGLIB_TOUPPER(p[t + n_leading_chars]);
}
@ -596,37 +596,20 @@ strtounicode(Py_UNICODE *buffer, const char *charbuffer)
{
register Py_ssize_t i;
Py_ssize_t len = strlen(charbuffer);
for (i = len - 1; i >= 0; i--)
for (i = len - 1; i >= 0; --i)
buffer[i] = (Py_UNICODE) charbuffer[i];
return len;
}
#endif
/* the callback function to call to do the actual float formatting.
it matches the definition of PyOS_ascii_formatd */
typedef char*
(*DoubleSnprintfFunction)(char *buffer, size_t buf_len,
const char *format, double d);
/* just a wrapper to make PyOS_snprintf look like DoubleSnprintfFunction */
static char*
snprintf_double(char *buffer, size_t buf_len, const char *format, double d)
{
PyOS_snprintf(buffer, buf_len, format, d);
return NULL;
}
/* see FORMATBUFLEN in unicodeobject.c */
#define FLOAT_FORMATBUFLEN 120
/* much of this is taken from unicodeobject.c */
/* use type instead of format->type, so that it can be overridden by
format_number() */
static PyObject *
_format_float(STRINGLIB_CHAR type, PyObject *value,
const InternalFormatSpec *format,
DoubleSnprintfFunction snprintf)
format_float_internal(PyObject *value,
const InternalFormatSpec *format)
{
/* fmt = '%.' + `prec` + `type` + '%%'
worst case length = 2 + 10 (len of INT_MAX) + 1 + 2 = 15 (use 20)*/
@ -658,6 +641,7 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
char* trailing = "";
STRINGLIB_CHAR *p;
NumberFieldWidths spec;
STRINGLIB_CHAR type = format->type;
#if STRINGLIB_IS_UNICODE
Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN];
@ -692,8 +676,8 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
PyOS_snprintf(fmt, sizeof(fmt), "%%.%" PY_FORMAT_SIZE_T "d%c", precision,
(char)type);
/* call the passed in function to do the actual formatting */
snprintf(charbuf, sizeof(charbuf), fmt, x);
/* do the actual formatting */
PyOS_ascii_formatd(charbuf, sizeof(charbuf), fmt, x);
/* adding trailing to fmt with PyOS_snprintf doesn't work, not
sure why. we'll just concatentate it here, no harm done. we
@ -719,8 +703,8 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
and skip it */
sign = p[0];
if (sign == '-') {
p++;
n_digits--;
++p;
--n_digits;
}
calc_number_widths(&spec, sign, n_digits, format);
@ -743,15 +727,6 @@ _format_float(STRINGLIB_CHAR type, PyObject *value,
done:
return result;
}
static PyObject *
format_float_internal(PyObject *value, const InternalFormatSpec *format)
{
if (format->type == 'n')
return _format_float('f', value, format, snprintf_double);
else
return _format_float(format->type, value, format, PyOS_ascii_formatd);
}
#endif /* FORMAT_FLOAT */
/************************************************************************/

View File

@ -186,6 +186,15 @@ PyOS_ascii_strtod(const char *nptr, char **endptr)
}
/* From the C99 standard, section 7.19.6:
The exponent always contains at least two digits, and only as many more digits
as necessary to represent the exponent.
*/
#define MIN_EXPONENT_DIGITS 2
/* see FORMATBUFLEN in unicodeobject.c */
#define FLOAT_FORMATBUFLEN 120
/**
* PyOS_ascii_formatd:
* @buffer: A buffer to place the resulting string in
@ -197,8 +206,10 @@ PyOS_ascii_strtod(const char *nptr, char **endptr)
* Converts a #gdouble to a string, using the '.' as
* decimal point. To format the number you pass in
* a printf()-style format string. Allowed conversion
* specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'.
* specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'n'.
*
* 'n' is the same as 'g', except it uses the current locale.
*
* Return value: The pointer to the buffer with the converted string.
**/
char *
@ -207,17 +218,23 @@ PyOS_ascii_formatd(char *buffer,
const char *format,
double d)
{
struct lconv *locale_data;
const char *decimal_point;
size_t decimal_point_len, rest_len;
char *p;
char format_char;
size_t format_len = strlen(format);
/* For type 'n', we need to make a copy of the format string, because
we're going to modify 'n' -> 'g', and format is const char*, so we
can't modify it directly. FLOAT_FORMATBUFLEN should be longer than
we ever need this to be. There's an upcoming check to ensure it's
big enough. */
char tmp_format[FLOAT_FORMATBUFLEN];
/* g_return_val_if_fail (buffer != NULL, NULL); */
/* g_return_val_if_fail (format[0] == '%', NULL); */
/* g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); */
format_char = format[strlen(format) - 1];
/* The last character in the format string must be the format char */
format_char = format[format_len - 1];
/* g_return_val_if_fail (format_char == 'e' || format_char == 'E' || */
/* format_char == 'f' || format_char == 'F' || */
@ -227,43 +244,126 @@ PyOS_ascii_formatd(char *buffer,
if (format[0] != '%')
return NULL;
/* I'm not sure why this test is here. It's ensuring that the format
string after the first character doesn't have a single quote, a
lowercase l, or a percent. This is the reverse of the commented-out
test about 10 lines ago. */
if (strpbrk(format + 1, "'l%"))
return NULL;
if (!(format_char == 'e' || format_char == 'E' ||
format_char == 'f' || format_char == 'F' ||
format_char == 'g' || format_char == 'G'))
format_char == 'g' || format_char == 'G' ||
format_char == 'n'))
return NULL;
/* Map 'n' format_char to 'g', by copying the format string and
replacing the final 'n' with a 'g' */
if (format_char == 'n') {
if (format_len + 1 >= sizeof(tmp_format)) {
/* The format won't fit in our copy. Error out. In
practice, this will never happen and will be detected
by returning NULL */
return NULL;
}
strcpy(tmp_format, format);
tmp_format[format_len - 1] = 'g';
format = tmp_format;
}
/* Have PyOS_snprintf do the hard work */
PyOS_snprintf(buffer, buf_len, format, d);
locale_data = localeconv();
decimal_point = locale_data->decimal_point;
decimal_point_len = strlen(decimal_point);
/* Get the current local, and find the decimal point character (or
string?). Convert that string back to a dot. Do not do this if
using the 'n' (number) format code. */
if (format_char != 'n') {
struct lconv *locale_data = localeconv();
const char *decimal_point = locale_data->decimal_point;
size_t decimal_point_len = strlen(decimal_point);
size_t rest_len;
assert(decimal_point_len != 0);
assert(decimal_point_len != 0);
if (decimal_point[0] != '.' ||
decimal_point[1] != 0)
{
p = buffer;
if (decimal_point[0] != '.' || decimal_point[1] != 0) {
p = buffer;
if (*p == '+' || *p == '-')
p++;
if (*p == '+' || *p == '-')
p++;
while (isdigit((unsigned char)*p))
p++;
while (isdigit(Py_CHARMASK(*p)))
p++;
if (strncmp(p, decimal_point, decimal_point_len) == 0)
{
*p = '.';
p++;
if (decimal_point_len > 1) {
rest_len = strlen(p + (decimal_point_len - 1));
memmove(p, p + (decimal_point_len - 1),
rest_len);
p[rest_len] = 0;
if (strncmp(p, decimal_point, decimal_point_len) == 0) {
*p = '.';
p++;
if (decimal_point_len > 1) {
rest_len = strlen(p +
(decimal_point_len - 1));
memmove(p, p + (decimal_point_len - 1),
rest_len);
p[rest_len] = 0;
}
}
}
}
/* If an exponent exists, ensure that the exponent is at least
MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
for the extra zeros. Also, if there are more than
MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
back to MIN_EXPONENT_DIGITS */
p = strpbrk(buffer, "eE");
if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
char *start = p + 2;
int exponent_digit_cnt = 0;
int leading_zero_cnt = 0;
int in_leading_zeros = 1;
int significant_digit_cnt;
p += 2;
while (*p && isdigit(Py_CHARMASK(*p))) {
if (in_leading_zeros && *p == '0')
++leading_zero_cnt;
if (*p != '0')
in_leading_zeros = 0;
++p;
++exponent_digit_cnt;
}
significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;
if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
/* If there are 2 exactly digits, we're done,
regardless of what they contain */
}
else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
int extra_zeros_cnt;
/* There are more than 2 digits in the exponent. See
if we can delete some of the leading zeros */
if (significant_digit_cnt < MIN_EXPONENT_DIGITS)
significant_digit_cnt = MIN_EXPONENT_DIGITS;
extra_zeros_cnt = exponent_digit_cnt - significant_digit_cnt;
/* Delete extra_zeros_cnt worth of characters from the
front of the exponent */
assert(extra_zeros_cnt >= 0);
/* Add one to significant_digit_cnt to copy the
trailing 0 byte, thus setting the length */
memmove(start,
start + extra_zeros_cnt,
significant_digit_cnt + 1);
}
else {
/* If there are fewer than 2 digits, add zeros
until there are 2, if there's enough room */
int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
if (start + zeros + exponent_digit_cnt + 1
< buffer + buf_len) {
memmove(start + zeros, start,
exponent_digit_cnt + 1);
memset(start, '0', zeros);
}
}
}