From the docs for built-in function "round":
"If ndigits is omitted, it defaults to zero"
(http://docs.python.org/3/library/functions.html#round)
But, the only way to get an integer from `round` is by not having the second argument (ndigits):
>>> round(3.5)
4
>>> round(3.5, 1)
3.5
>>> round(3.5, 0)
4.0
>>> round(3.5, -1)
0.0
>>> round(3.5, None)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
round(3.5, None)
TypeError: 'NoneType' object cannot be interpreted as an integer
Either the docs are wrong or the behavior is wrong. I think it's easier to fix the former...
But also there should be a way to make round return an integer (e.g. passing `None` as 2nd argument)

Thanks. It's inaccurate to say that a float is returned in general, though: for most builtin numeric types, what's returned has the same type as its input. So rounding a Decimal to two places gives a Decimal on output, etc. (That's already explained in the next paragraph.)

> I don't understand. There's already a way to make round return an integer: don't pass a second argument.
If this function were to be written in Python, it would be something like:
def round(number, ndigits=0):
...
or
def round(number, ndigits=None):
...
But in C you can forge the signature to whatever you want and parse the arguments accordingly. In Python there's always a way to get the default behavior by passing the default argument, but in C it may not exist (in this case `PyObject *o_ndigits = NULL;`)
So, I propose the default value being `None`, so this behavior can be achieved using a second argument.

> Anyway, why not round(1.2) -> 1.0 in the first place? Just curious.
It was the behavior on Python 2.x, but somehow when they changed the rounding method to nearest even number this happened... I think it's too late to change back the return type.

Do you have any real-world motivating use case for None? Not just theoretical consistency with what a Python version of the function would look like. (I'm not saying we shouldn't consider supporting None as a low priority change, I'm just trying to figure out where you'd ever need it in the real world.)

Right, but None in that case has real world utility, since you might have the the value in a variable. But you are hardly going to hold int-or-not in a variable, especially a variable that is really about the number of places in the float result...

> Anyway, why not round(1.2) -> 1.0 in the first place? Just curious.
All this changed as part of PEP 3141. I wasn't watching Python 3 development closely back then, but I *think* at least part of the motivation was to provide a way to get away from the use of `int` to truncate a float to its integer part: the argument goes that a simple type conversion shouldn't throw away information, and that if you want a transformation from float to int that throws away information you should ask for it explicitly. So `math.trunc` was born as the preferred way to truncate a float to an int, and `math.floor`, `math.ceil` and `round` became alternative float -> int conversion methods. That entailed those functions returning ints.
<off-topic> In the case of `math.floor` and `math.ceil` at least, I think this is regrettable. There are plenty of places where you just want a float -> float floor or ceiling, and Python no longer has a cheap operation for that available: floor as a float-to-float operation is cheap; floor as a float-to-long-integer operation is significantly more costly.
In the case of `round`, we still have `round(x, 0)` available as a cheap float->float conversion, so it's less of a problem. And I hardly ever use `trunc`, so I don't care about that case. </off-topic>

In case we want to add consistency with None ndigits, here is the patch adding support for None value for ndigits parameter.
This one looks like a low-risk addition but since Python 3.4 is in beta phase....

The docstring is better than the current doc as it says that the default precision is 0, without calling that the default for ndigits.
''' round(number[, ndigits]) -> number
Round a number to a given precision in decimal digits (default 0 digits).
This returns an int when called with one argument, otherwise the
same type as the number. ndigits may be negative.'''
---
Sidenote: To write round in Python, one could easily write
_sentinel = object
def round(number, ndigits=_sentinel):
if ndigits is _sentinel: ...
which makes ndigits positional-or-keyword, and almost optional-with-no-default, as _sentinel is close enough to being a default that cannot be passed in. This is a standard idiom. One who was really picky about having no default could use
def round(number, *args, **kwds): ...
and look for len(args) == 1 xor kwds.keys() == {'ndigits'}.