[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-06 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

No worries Robert.  It's all part of the process :-)

If it's okay with you.  I would like to revert the incorrectly applied PR and 
then you can build a fresh, clean patch.  Does that work for you?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-06 Thread Guido van Rossum


Change by Guido van Rossum :


--
assignee: gvanrossum -> rhettinger
nosy:  -gvanrossum

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-06 Thread Robert Smallshire


Robert Smallshire  added the comment:

First, I would like to apologise for the confusion I have inadvertently caused. 
I didn't see Raymond's question and Guido's clear response here about not 
modifying the numeric tower, as it came _long_ after activity had moved to 
GitHub, and code had been reviewed over there. Now Raymond has linked back to 
here and I've caught up with the situation, I offer to make a compensating PR 
with reverts the changes to the numeric tower. I should be able to do this in 
the next day or two.

Please let me know whether you would like me to proceed, or whether you intend 
to handle the a partial or complete rollback among yourselves.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-06 Thread Serhiy Storchaka


Change by Serhiy Storchaka :


--
priority: normal -> release blocker

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-06 Thread Mark Dickinson


Change by Mark Dickinson :


--
nosy:  -mark.dickinson

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-05 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

> I would have assumed that it's only making a promise that it 
> registers all the methods and properties marked *abstract* in
> the ABC. Do you have references to back up the stronger statement?

The isn't some weird or incidental promise.  It is the fundamental reason that 
abstract base classes exist at all (and not just in Python).

>From PEP 3119: "Each test carries with it a set of promises: it contains a 
>promise about the general behavior of the class, and a promise as to what 
>other class methods will be available."

>From PEP 3119: "In addition, the ABCs define a minimal set of methods that 
>establish the characteristic behavior of the type. Code that discriminates 
>objects based on their ABC type can trust that those methods will always be 
>present."

> we need to either (a) revert PR 6121 and then re-do the changes,
> without the changes to numbers.py, or (b) make a second PR to undo
> the numbers.py changes.

Given that (b) can't be done in the short-run, I recommend option (a) so that 
there is a single clean patch and to make sure this doesn't leak into a 
release.  The PR changed 19 files, so the longer we wait the harder it will be 
to revert cleanly.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-05 Thread Mark Dickinson


Mark Dickinson  added the comment:

[Guido]

> Possibly at some point in the future we can switch to using typing.Protocol 
> [...]

Yes, I think there's an interesting wider problem here, that typing.Protocol 
might be the answer to.

For numbers and collections.abc in the std. lib., I'm happy to accept that 
simply having a method present in the relevant ABC class implicitly makes it a 
part of the interface (though it would be good if that were clarified 
somewhere).

But in our own code, we've found it convenient to have abc.ABC subclasses that 
are a combination of interface and convenience base class, with the external 
interface separated from the convenience methods via the @abstractmethod and 
@abstractproperty decorators: classes that register with the given ABC subclass 
must provide all methods marked with those decorators, but the other methods 
are not considered part of the formal interface, and not used by client code 
that expects only an object implementing that interface.

The alternative to that convenience is to have two classes: a separate purely 
abstract interface, and a base class implementing that interface that's 
designed for subclassing. That works too, but it's a bit unwieldy, and it's 
useful to have the all-in-one option available.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-05 Thread Mark Dickinson


Mark Dickinson  added the comment:

Ok, so we need to either (a) revert PR 6121 and then re-do the changes, without 
the changes to numbers.py, or (b) make a second PR to undo the numbers.py 
changes. I think there's (calendar) time available for option (b), but I'm not 
going to have bandwidth to do it any time soon, so there's a risk that the 
current changes make it into Python 3.10 purely through inertia. What's the 
best approach here?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-05 Thread Mark Dickinson


Mark Dickinson  added the comment:

> When a concrete class registers with an ABC, it is making a promise that it 
> implements everything in the ABC.

Ah, interesting. I would have assumed that it's only making a promise that it 
registers all the methods and properties marked *abstract* in the ABC. Do you 
have references to back up the stronger statement?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-04 Thread Guido van Rossum


Guido van Rossum  added the comment:

Possibly at some point in the future we can switch to using typing.Protocol, 
which requires neither registration nor explicit subclassing (it's like 
Hashable). This makes it easy for user code to define custom protocols as 
needed. So if you need something that has .keys() and .items() but you don't 
care about .values() you can just write

class KeysAndItems(typing.Protocol):
def keys(self): ...
def items(self): ...

def my_func(x: KeysAndItems):
...

This can be statically checked using e.g. mypy.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-04 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

> How so?

When a concrete class registers with an ABC, it is making a promise that it 
implements everything in the ABC so that client code can count on all the 
methods being present.  That is the raison d'etre for abstract base classes.

In general, we restrict ABCs to a minimal useful subset of the capabilities of 
concrete classes.  That makes the ABC more broadly applicable and it makes life 
easier for implementers of concrete classes.  That's why collections.abc.Set 
doesn't include most of the named methods present in the concrete set/frozenset 
types.

Likewise, we don't want to add methods to already published ABCs because 
existing user classes registered to the ABC stop being compliant.  If an 
additional method is deemed essential, the technically correct way to do is to 
make a new ABC that subclasses from the old.  For example, that's why Python 2 
had to have both UserDict and IterableUserDict when we needed to add a 
__iter__() method.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-04 Thread Mark Dickinson


Mark Dickinson  added the comment:

> That still amounts to making it a requirement for all numeric classes

How so? I don't follow the reasoning here.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-04 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

>  it was added as a concrete method,

That still amounts to making it a requirement for all numeric classes, even 
ones that predate this patch.  So existing classes that are registered will no 
longer comply with the ABC.  

In general, it's hard to add methods to ABCs because an ABC makes a promise 
about what methods are available in any class registered to that ABC.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-04 Thread Mark Dickinson


Mark Dickinson  added the comment:

I interpreted "in the numeric tower" as meaning declared as an abstract method 
that all those registering with the class would have to implement. As you point 
out in msg350173, that would be problematic - adding new methods to published 
interfaces is pretty much a no-no for backwards compatibility reasons.

But that's not what happened here. Robert's original patch *did* add is_integer 
as an abstract method. The PR that was merged did not - it was added as a 
concrete method, as a convenience for those using the ABCs via direct 
subclassing rather than registering.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-03 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

Mark, why did this get merged with is_integer() still in the numeric tower?  I 
thought we had agreed not to do that.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2020-10-01 Thread Mark Dickinson


Mark Dickinson  added the comment:


New changeset 58a7da9e125422323f79c4ee95ac5549989d8162 by Robert Smallshire in 
branch 'master':
bpo-26680: Incorporate is_integer in all built-in and standard library numeric 
types (GH-6121)
https://github.com/python/cpython/commit/58a7da9e125422323f79c4ee95ac5549989d8162


--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2019-08-22 Thread Guido van Rossum


Guido van Rossum  added the comment:

It should not go on the numeric tower.
-- 
--Guido (mobile)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2019-08-22 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

Guido, when you approved this did you intend for the numeric tower to be 
amended as well?  We elected not to do so for as_integer_ratio() and the same 
choice should be made here (because it's hard to add methods to ABCs without 
breaking existing user classes registered to that ABC).

FWIW, it's not too late to change your mind about doing this at all. I don't 
see this as a feature in other languages and even the ultra thorough decimal 
arithmetic specification elected not to include this method.  The benefits are 
somewhat dubious but new method counts are certain:   len(dir(int)) == 72

--
assignee:  -> gvanrossum
nosy: +gvanrossum

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2019-08-22 Thread Raymond Hettinger


Change by Raymond Hettinger :


--
resolution: rejected -> 
versions: +Python 3.9 -Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2019-08-22 Thread Robert Smallshire


Robert Smallshire  added the comment:

> * no forward movement for a year and half

For most of that year and a half my pull-request was sitting in Github 
 awaiting review by two core devs, 
of which you Raymond, were one. I don't like to hassle people who contribute 
their free time to Python and assumed you or the other reviewer would get 
around to it good time. Mark Dickinson kindly reviewed the my changes shortly 
before the 3.8 window closed, but I didn't have capacity to follow up before it 
was too late. The changes Mark wanted were largely to do with in-code 
documentation rather than the the substance of the change.

Assuming it really is too late for 3.8, even if I made the changes Mark wanted 
immediately, I would like to see this change in 3.9.

> * opposition from multiple core devs

Guido approved the change in a pronouncement on python-dev. 


--
status: closed -> open

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2019-08-22 Thread Raymond Hettinger


Raymond Hettinger  added the comment:

Marking this as closed:
* no forward movement for a year and half 
* opposition from multiple core devs

Feel free to revive this if you truly think this is needed and want to get the 
debate going again.

Also, expanding the numeric tower is always going to be problematic, because 
any user type that currently registers with it will be instantly non-compliant. 
 Concrete classes can grow APIs and keep backwards compatibility but abstract 
classes cannot easily grow new requirements.

--
resolution:  -> rejected
stage: patch review -> resolved
status: open -> closed

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Christian Heimes

Christian Heimes  added the comment:

/me bets his money on Stefan and Tim

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Tim Peters

Tim Peters  added the comment:

If you want to deprecate the method, bring that up on python-dev or 
python-ideas.  It's inappropriate on the issue tracker (unless, e.g., you open 
a new issue with a patch to rip it out of the language).  It's also 
inappropriate to keep on demanding in _this_ issue that people justify a method 
that already exists.  For that reason, I'm not responding again to more 
repetitions of that here.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

I am proposing to deprecate float.is_integer() and remove it in 3.10. After 
deprecating float.as_integer() we shouldn't bother about adding 
int.is_integer().

If this method is necessary in implementing various math libraries please show 
me the code of these libraries that call float.is_integer() or which will get a 
benefit from adding is_integer() in int and Decimal.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Tim Peters

Tim Peters  added the comment:

Serhiy, nobody is proposing to add float.as_integer().  It already exists:

>>> (3.1).is_integer()
False

I already allowed I don't have a feel for how _generally_ useful it is, but you 
have at least my and Stefan's word for that the functionality (however spelled) 
_is_ necessary in implementing various math libraries.

If we outlawed float functions that the numerically naive may misuse, we'd have 
to remove floats entirely.

Given that it's _already in the language_, the only question here is whether to 
make it play nice with types beyond just `float`.  I expect you'd have a hard 
time constructing an example where int.is_integer() returned a misleading 
result ;-)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

I do not see a point in adding a function that will never be used correctly.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Tim Peters

Tim Peters  added the comment:

[Raymond]
> The OPs notion of "absurd" behavior implies a rule that
> all float methods should be available for ints.  That
> would suggest the is_integer, hex, fromhex, and
> as_integer_ratio would all need to propagate to the
> other types as well.  I don't think we should start
> sliding down that slope.

Given that Guido recently said it was absurd that int.hex() doesn't exist, and 
that another PR to add int.as_integer_ratio() is in progress, we'll soon be 
halfway down that slope looking up ;-)

The OP is right that in a world where you _can't tell_ from staring at the code 
whether you'll get back an int or a float, sometimes not even when you know the 
input types (like `int**int`), it can be jarring when degenerate cases (like 
int.is_integer()) refuse to do the obvious thing.

So I'm in favor given that float.is_integer() already exists.

While I have no feel for how generally useful is_integer() may be, there are 
many use cases when _implementing_ math functions.  For example,

>>> (-1.0) ** 3.1
(-0.9510565162951536-0.30901699437494706j)
>>> (-1.0) ** 3.0
-1.0

Here not only the value, but the _type_ of the result depends on whether the 
power is an exact integer.  The only way to know the latter is to spell 
is_integer() in _some_ way.  Given that x is a finite double, `x == int(x)` may 
be used in Python, or `x == floor(x)` in C or even `fmod(fabs(x), 1.0) == 0.0`.

As Mark pointed out, those kinds of ways can be woefully inefficient for 
Decimals, so adding is_integer() to Decimal too supplies a uniform way for 
users to spell the functionality that types can implement in a way best for 
them.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Facundo Batista

Change by Facundo Batista :


--
nosy:  -facundobatista

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Robert Smallshire

Robert Smallshire  added the comment:

Serhiy, you asked for use cases, not uses. The former can exist without the 
latter.  Use cases for is_integer() include all existing uses of x == int(x), 
or other less obvious means of detecting integer values.

Folks try to use x.is_integer(), discover it fails if x is an int, and go in 
search of a replacement, which may well be x == int(x), which goes on to fail 
in more complex and awkward to handle ways with NaN or Inf.

I've seen is_integer() used in guard clauses for functions which accept numbers 
which require an integral value (Recall that explicit type checking is usually 
called out as unPythonic, and rightly so). The Python factorial is example of 
such a function which makes an equivalent check. StackOverflow is awash with 
folks using isinstance(x, int) where that is not what they actually mean. Many 
of these are the same use-case, but don't use is_integer().

I've also seen it used in cases where different algorithms are more optimal 
depending on whether the arguments are integral or not (imagine some 
combination of factorial() and gamma()).

I've seen it used in conversion from float to custom number types used to 
simulate the unusual number types in embedded hardware.

I'm not going to engage with this discussion further. It's already consumed too 
much of my time, left me with a somewhat negative view of how Python 
development proceeds, and a confused view of the values that are most important 
to the Python language.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Stefan Krah

Change by Stefan Krah :


--
nosy:  -skrah

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

If float.is_integer() is useful in numerical code please give me few examples.

I don't take your argument about mpd_as_integer() in the Decimal class. Decimal 
has a lot of methods which makes sense for Decimal.

>>> len(set(dir(decimal.Decimal)) - set(dir(numbers.Rational)))
55

Do you suggests to add all of them into the numeric tower?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Stefan Krah

Stefan Krah  added the comment:

libmpdec is an example of numerical code.  I don't think anyone but you has 
argued that is_integer() is useless in numerical code.  Whether it is float or 
decimal doesn't matter.

I get the API-bloat argument, but I'm completely surprised that anyone would 
assert the above.


I think searching GitHub or the Internet for robust numerical code is not 
conclusive.  80% of open source stuff is probably derived from netlib anyway. 
:-)



I'll avoid giving examples outside of libmpdec because I don't have time for a 
nitpicking war. :-)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

mpd_as_integer() is used internally in the Decimal class. Do you have use cases 
for it outside of the Decimal class?

And the question was about using float.is_integer(). I have not found *any* 
sane example on GitHub. The most harmless is just a demo

>>> x = 3.0
>>> print(x.is_integer())
True

Other examples are so bad that make me angry.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Stefan Krah

Stefan Krah  added the comment:

In effect:

   "!(Py_IS_FINITE(dx) && dx == floor(dx))"


I don't understand why Robert is questioned so much. mpd_as_integer() (or 
rather the optimized version _mpd_isint() is used all over the place inside 
libmpdec's own numeric code.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

math.factorial() doesn't use float.is_integer().

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Robert Smallshire

Robert Smallshire  added the comment:

Python in effect contains an example itself. The math.factorial(x) function 
contains what is in-effect an is_integer() check as a guard.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

The use case of is_integer() still is not clear. Could you give examples of the 
correct use of this method in real projects?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-15 Thread Robert Smallshire

Change by Robert Smallshire :


--
pull_requests: +5885
stage: needs patch -> patch review

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

As for StackOverflow links provided by Robert, it looks to me that 
float.is_integer() is always used improperly.

If keep this method it would be worth to warn against improper use of it.

Bad:

(x/5).is_integer()

Good:

x % 5 == 0

or

not x % 5

Bad:

math.sqrt(x).is_integer()

Good:

int(math.sqrt(x))**2 == x

Bad:

while x < y:
if x.is_integer():
print(x)
x += 0.1

Good (if initial x was integer):

x0 = x
i = 0
while x < y:
x = x0 + i/10
if not i % 10:
print(x)
i += 1

And provide an example of a *proper* use case (if it exists).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Robert Smallshire

Robert Smallshire  added the comment:

Thank you Raymond. I'll work up a PR shortly.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

I would rather deprecate float.is_integer() if it looks as a magnet of bad code.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Raymond Hettinger

Raymond Hettinger  added the comment:

Robert, would you please update you patch and submit it to Github as a pull 
request.  It is looking like this will likely go forward after all.

--
stage: patch review -> needs patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Stefan Krah

Stefan Krah  added the comment:

I agree with Mark's mailing list statements: There is no ambiguity
for decimal, given that the existing predicates ignore the context.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

What is the use case of float.is_integer() at all? I haven't found its usages 
in large projects on GitHub. Only in playing examples where it is (mis)used in 
cases like (x/5).is_integer() (x % 5 == 0 is better) or (x**0.5).is_integer() 
(wrong for some floats or large integers).

Maybe it should be removed in Python 3.0.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Mark Dickinson

Mark Dickinson  added the comment:

Ongoing discussion here: 
https://mail.python.org/pipermail/python-dev/2018-March/152358.html

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Raymond Hettinger

Change by Raymond Hettinger :


--
versions: +Python 3.8 -Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Serhiy Storchaka

Serhiy Storchaka  added the comment:

float.is_integer() was added 6f34109384f3a78d5f4f8bdd418a89caca19631e 
(unfortunately no issue number for looking at the discussion preceded it). I 
don't know reasons. The same changeset added implementations of 
complex.is_finite(), int.is_finite(), long.is_finite(), float.is_inf() and 
float.is_nan(), but they were disabled by default (they are still a dead code 
in sources). The same changeset added well known functions math.isinf(), 
math.isnan(), cmath.isinf() and cmath.isnan().

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Robert Smallshire

Robert Smallshire  added the comment:

Apologies for the email splurge. That's the first and last time I'll use the 
email interface to bugs.python.org.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Robert Smallshire

Robert Smallshire  added the comment:

To respond to Raymond's points:

1) Nobody is suggesting that every float method should also be available on
int.  Clearly some methods on float are not applicable to int.

2) Taken narrowly, you're right that is_integer() does nothing useful for
int.  Neither do imag, denominator, __floor__, or __trunc__. They're all
present so we can successfully use integers in duck-typing situations along
with the other number types. My claim is that int.is_integer() is useful
for the same reasons.

The problem isn't that you or I don't know that we should write a == int(a)
to be portable, the problem is that code that *already* uses x.is_integer()
fails hard when x happens to be an int. As I've demonstrated, some built-in
operators and functions can return either int or float, even when the
operand types are all int, depending only on the *values* of the operands.

This wouldn't matter if nobody ever wrote f.is_integer(), and instead used
the trivially portable solution, but they do, and at your behest: In 2011
you published "f.is_integer() is the new way to test whether a float is
integral. The old way, x==int(x), is history."  The reality is that folks
often write Python functions which accept *numbers*, without giving too
much thought to whether calling my_func(42.0) will work, but my_func(42)
will cause an unhandled exception that nobody is expecting. Indeed, one of
the joys of Python is that we often don't need to overthink this.

The trivial portable solution is also nearly three times slower than
float.is_integer() and int.is_integer(). Moreso if you package it up in a
function so it can be applied to more complex expressions in, say, a
comprehension, where an intermediate assignment is not possible.

I'm not the only person to be thrown by this. See this:

is_integer() not working: https://stackoverflow.com/
questions/17170226/is-integer-not-working/17170511

and this:

   https://www.reddit.com/r/learnpython/comments/4tp4hy/
need_help_with_identify_number_as_integer/

and this

https://wiesmann.codiferes.net/wordpress/?p=13366

Furthermore, once the is_integer() method is discovered, it leads to folks
writing odd code in order to leverage it, such as always converting user
integer input to float in order to check that it's really is an integer
(which of course subtly limits the precision of allowable integers).
There's an example of this on page 14 of the book *Doing Math With Python*.
https://www.amazon.com/Doing-Math-Python-Programming-Statistics/dp/1593276400

Other prolific and widely respected Python programmers have described this
behaviour as "kind of nuts" (though I'm not going to involve them here).
The behaviour has also invited unfortunate comparisons with similar
non-obvious behaviour in Javascript.

3) I'd be very surprised if the presence of this method on int caused any
more confusion, or impediment to learning than do the presence of int.imag
or int.denominator.

4) I'm less bothered about the numeric tower aspect than I am about
duck-type compatibility between the built-in types int and float. That
said, a key part of what I think is your concern about creating work for
subclass implementers can be addressed by providing a default
implementation Real.is_integer() in terms of int(x) == x.

5) The decimal spec doesn't require an is_decimal function, but it doesn't
forbid it either. In any case, the Decimal implementation already
implements is_integer internally as `cpx_mpd_isinteger` – and uses it a
great deal, which demonstrates its utility. My patch simply exposes it to
Python. There's no danger of violating any specification, unless that
specification says that you must not implement a method called is_integer,
which it doesn't, especially as we would be using a definition which is
already de facto compatible with the standard.  I don't care very much
about Decimal either for my own work, especially as it already stands apart
from the numeric tower. I implemented it to be consistent with my argument
about duck typed numbers (which still largely holds for Decimal, except for
floor division and modulus I believe).

Solutions for which use `a == int(a)` or `a == a.to_integral_value()` fail
for NaN and infinities, whereas float.is_integer() is more robust. It turns
out the trivial portable solution isn't so trivial, or so portable, if
implemented robustly, performantly and with duck-typing in mind.

Ultimately, my argument is one about duck typing across numbers types. If
if that abstraction isn't valued, I have nowhere to go.

*Robert Smallshire | *Managing Director
*Sixty North* | Applications | Consulting | Training
r...@sixty-north.com | T +47 63 01 04 44 | M +47 924 30 350
http://sixty-north.com

On 11 March 2018 at 05:58, Raymond Hettinger  wrote:

>
> Raymond Hettinger  added the comment:
>
> Sorry Robert, but I object to this going forward.
>
> 1) We do not and 

[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-12 Thread Mark Dickinson

Mark Dickinson  added the comment:

One quibble with Raymond's response:

> 2) Your use case is trivially solved in a portable, trivial, and readable > 
> way:
> 
>a == int(a)

For Decimal, I'd recommend using `a == a.to_integral_value()` instead. Using  
`a == int(a)` will be inefficient if `a` has large exponent, so it's not a good 
general-purpose solution (though it's probably good enough in most real-world 
cases).

Here's an extreme example:

In [1]: import decimal
In [2]: x = decimal.Decimal('1e9')
In [3]: %timeit x == int(x)
1.42 s ± 6.27 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [4]: %timeit x == x.to_integral_value()
230 ns ± 2.03 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-10 Thread Raymond Hettinger

Raymond Hettinger  added the comment:

Sorry Robert, but I object to this going forward.

1) We do not and should not require that every float() method also be in int():

   >>> set(dir(float)) - set(dir(int))   
   {'fromhex', 'hex', 'is_integer', '__getformat__', '__setformat__', 
'as_integer_ratio'}

2) Your use case is trivially solved in a portable, trivial, and readable way:

   a == int(a)

3) I really don't want to clutter the other types with this method when it does 
nothing useful for those types.  In particular, I expect that the presence of 
"is_integer()" in the int() class will likely create more confusion than it 
solves (perhaps not for you, but for the vast majority of users, none of whom 
have ever requested this behavior over the entire history of the language).

4) Also, I don't what this to have to propagate to every project that ever 
registers their custom numeric types with the numeric tower.  Adding this 
method to the tower is essentially making a requirement that everyone, 
everywhere must add this method.   That is not in the spirit of what the ABCs 
are all about -- they mostly require a small and useful subset of the behaviors 
of the related concrete classes (i.e. the concrete collections all have more 
methods than are required by their collections.abc counterparts).

5) Lastly, the spirit of the decimal module was to stick as closely as possible 
to the decimal specification and assiduously avoid extending the spec with new 
inventions (risking duplication of functionality, risking non-portability with 
other implementations, risking not handling special values in a way that is 
consistent with the spec, risking our going down a path that intentionally not 
chosen by the spec creators, or risking being at odds with subsequent updates 
to the spec).

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2018-03-10 Thread Robert Smallshire

Robert Smallshire  added the comment:

I've recently run into this issue impeding duck-typing between int and float 
again, when used in conjunction the int.__pow__, which may variously return an 
int or float depending on the value - not the type - of the arguments.

This is succinctly demonstrated by this example:

  >>> (10 ** -2).is_integer()
  False
  >>> (10 ** 2).is_integer()
  Traceback (most recent call last):
File "", line 1, in 
  AttributeError: 'int' object has no attribute 'is_integer'

I hear the argument about Python being harder to learn if more methods are 
supported on the built-in types - and perhaps float.is_integer should never 
have been added, but now its there, but I think Python is harder to learn and 
teach in the presence of these differences. Is is harder to learn "Real numbers 
support an is_integer() method", than it is "float supports an is_integer() 
method"?

I'm happy to put in the work bring my original patches up-to-date, or create a 
PR depending on what current process is.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-05 Thread Robert Smallshire

Robert Smallshire added the comment:

Thanks Stefan for the illuminating example.

I knew I shouldn't have strayed off-topic.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-05 Thread Stefan Krah

Stefan Krah added the comment:

On Tue, Apr 05, 2016 at 02:20:19PM +, Robert Smallshire wrote:
> >> Were float to inherit from Rational, rather than Real ...
> 
> > This would break the Liskov substitution principle.
> 
> How so?  Rational extends Real with only numerator, denominator and 
> __float__. Isn't the existence of float.as_integer_ratio demonstration that 
> numerator and denominator could be implemented?

Substitution principle:

Let phi(x) be a property provable about objects x of type T. Then phi(y) should
be true for objects y of type S where S is a subtype of T.

Use:

  Let phi(n) = forall n: n elt nat => (1 / n) * n == 1

Counterexample:

   n == 9992

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-05 Thread Robert Smallshire

Robert Smallshire added the comment:

>> Were float to inherit from Rational, rather than Real ...

> This would break the Liskov substitution principle.

How so?  Rational extends Real with only numerator, denominator and __float__. 
Isn't the existence of float.as_integer_ratio demonstration that numerator and 
denominator could be implemented?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-05 Thread Stefan Krah

Stefan Krah added the comment:

On Tue, Apr 05, 2016 at 01:10:25PM +, Robert Smallshire wrote:
> Were float to inherit from Rational, rather than Real ...

This would break the Liskov substitution principle.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-05 Thread Robert Smallshire

Robert Smallshire added the comment:

Java makes no claim to have a numeric tower.  Amongst the dynamic languages I 
surveyed Matlab (isinteger), Javascript ES6 (isInteger), PHP (is_integer), R 
(is.integer), TCL (is entier), and as we have seen Scheme (integer?) all have 
methods for testing for integer values. Python has a numeric tower modelled on 
Scheme. In the Scheme documentation we find this:

"...the integer 5 may have several representations. Scheme's numerical 
operations treat number objects as abstract data, as independent of their 
representation as possible. Although an implementation of Scheme may use many 
different representations for numbers, this should not be apparent to a casual 
programmer writing simple programs."

This is what I'm advocating.

There isn't a single mathematical (as opposed to representational) method on 
int that isn't 'inherited' from the numeric tower.  There are exactly two 
methods on float which aren't inherited from the tower: is_integer and 
as_integer_ratio.  So I think it's would be a stretch to claim that "Most of 
the [numerical] ABCs have only a subset of the [numerical] methods in the 
[numerical] concrete types."

Rather than looking at the numeric tower as a construct which forces 
proliferation of methods, it would be better to look on it as a device to 
prevent bloat. I risk straying off topic here, but I want to give an example of 
why the numeric tower is important:

Were float to inherit from Rational, rather than Real (all finite floats are 
rationals with a power-of-two denominator, all Decimals are rationals with a 
power-of-ten denominator, so this is reasonable) then the as_integer_ratio 
method which was added to float and latterly Decimal 
(http://bugs.python.org/issue25928), arguably cluttering their interfaces, may 
have been deemed unnecessary. The numerator and denominator attributes present 
in Rational could have been used instead.  I think this is an example of lack 
of adherence to the numeric tower (at least in spirit in the case of Decimal) 
resulting in interface clutter or bloat.

The consequent control-flow complexity required handle numeric objects as 
'abstract data' is surprising: statistics._exact_ratio is a good example of 
this. I count five API tests just to be able to treat numbers as, well, just 
numbers.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-04 Thread Raymond Hettinger

Raymond Hettinger added the comment:

* For most users, this will just be noise (even the existing float method is 
rarely used).   It is unimportant enough that Python existed without it for a 
very long time and it is unimportant enough that it didn't arise during the 
lengthy process of creating the decimal module.  

* The numeric tower doesn't require that we take new methods and push them to 
every type whether or not it makes sense.  Most of the ABCs have only a subset 
of the methods in the concrete types.

* There are already simple workarounds using a try/except or a conditional 
expression.

-1 I really don't want more clutter added to all the numeric classes.  (Clutter 
being something rarely needed, easily implemented in other ways, something that 
looks weird or confusing in classes like int or Fraction, something that we 
have done without to 26 years, something not covered by the decimal spec, and 
something that isn't part of the floats API for either Java* or Smalltalk)

* http://www.tutorialspoint.com/java/lang/java_lang_float.htm

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-04 Thread Stefan Krah

Stefan Krah added the comment:

I agree that Robert's "absurdity" argument was unfortunate and could
be reversed: Many people would consider an (10).is_integer() method
absurd.

I'm also only moderately interested in OOP or classification in general, but  
we *do* have a numeric tower modeled after Scheme,
so here goes:

scheme@(guile-user)> (integer? 487)
$1 = #t
scheme@(guile-user)> (integer? 1.2)
$2 = #f
scheme@(guile-user)> (integer? 1.0)
$3 = #t
scheme@(guile-user)> (integer? 1/7)
$4 = #f
scheme@(guile-user)> (integer? 100/10)
$5 = #t
scheme@(guile-user)> 


The ACL2 theorem prover has the same:

ACL2 !>(integerp 100)
T
ACL2 !>(integerp 100/10)
T
ACL2 !>(integerp 100/7)
NIL


For me, these functions are something fundamental. I'd prefer
them to be exposed in a functional manner like above, but we
do have the numeric tower.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-04 Thread Robert Smallshire

Robert Smallshire added the comment:

To be clear, I'm not arguing that is_integer is in the same category as hex and 
fromhex; is_integer is a mathematical property of the number, whereas hex and 
from hex are representational. Nobody expects interoperability of string 
representations of the different number types.

Neither do I take issue with the general argument against enlarging the API. In 
fact, if float.is_integer did not exist, I would not be campaigning for it to 
be invented.

What I do take issue with is already having a method on float which makes sense 
for all Real numbers, but then not supporting it for those other Real types. 
This just gets in the way of programming generally in terms of *numbers* rather 
than concrete types, especially when the is_integer method is being advocated 
as the *right way* to do such a test. This is can lead to other problems as 
people unthinkingly convert other number types to floats, with loss of 
information, just to get access to this convenience method. 

I'm (really) surprised that structural typing and polymorphism over numbers 
carries so little weight – a cursory look at StackOverflow* shows that there 
are already too many people being encouraged to answer the 'is integral' 
question with isinstance(x, int) when that is not what they mean or need.

As a precedent we already have int.numerator, int.denominator, int.real and 
int.imag which are presumably using Raymond's argument are also 'total waste', 
but the reality is that the presence of these attributes causes no impediment 
to learning and makes many tasks easier with fewer special cases. When working 
with rationals, I frequently rely on the fact that ints implement the Rational 
interface.  When working with complex numbers, I frequently rely on the fact 
that both int and float implement the Complex interface. For example. I have 
used use these attributes in the constructor for a fixed-point number type, and 
was thankful for their existence.

I'm also happy to set the Decimal aspect of my proposal to one side as Decimal 
is explicitly outside the numeric tower.

This isn't about me avoiding writing trivial one-line functions or "the OPs use 
case". I'm trying to help you make Python more predictable and easier to use.  
I'm far from the first person to be surprised by this.

I'd be happy to trade adding is_integer to the numeric tower for a deprecation 
notice on float.is_integer - the outcome is the same - polymorphic number types 
with fewer special cases.







--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-04 Thread Raymond Hettinger

Raymond Hettinger added the comment:

FWIW, I think the reasoning in http://bugs.python.org/issue1093 applies here as 
well.  The need is insufficient to warrant inclusion in the numeric tower and 
propagation to types like int and Fraction.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-04 Thread Raymond Hettinger

Raymond Hettinger added the comment:

> the functions are so simple and self-explanatory 
> that API-complexity does not really increase.

It increases complexity because it will show-up everywhere including places 
where it makes little sense.

One place is int objects where its meaning and purpose will seem arcane to most 
Python programmers.  For int objects, this is just total waste.

With the fractions module, the method is also unnecessary because integral 
fractions all have a denominator of 1.

With the decimal module, we were careful not to grow the API beyond what was in 
the spec or what was necessary to integrate it into Python (i.e. the usual 
magic methods).  I think that was a good decision and would like to keep it 
that way. 

In general, the need for this method is almost nil (it would be a very, very 
rare Python programmer who would ever need this, and those that might what it 
are perfectly capable of writing a short function to handle their own 
requirements).  In the OPs case, the motivation isn't inability to determine 
whether something is integral, it is more a desire for the test to be 
polymorphic with other types where the methods do not add any real value.  

The OPs notion of "absurd" behavior implies a rule that all float methods 
should be available for ints.  That would suggest the is_integer, hex, fromhex, 
and as_integer_ratio would all need to propagate to the other types as well.  I 
don't think we should start sliding down that slope.

Another thought is that future updates to the decimal spec could make 
conflicting choices about what Decimal.is_integral() would return for 
Decimal('Infinity').  There could be a case to be made for true, for false, for 
NaN, or for setting one or more of the signal flags or traps.  

I'm glad that the OP separated out the request for Decimal given that his 
actual use cases involve everything except Decimal.  The decimal class is 
intentionally not registered a Real (only as a Number) because it isn't 
interoperable with binary floats; hence, there has been no need to copy all the 
float methods into Decimal.

AFAICT, this comes down to whether to push a float method into other types 
where we otherwise wouldn't do it, just to save the OP from one-line function:

is_integral = lambda x:  isinstance(x, int) or isinstance(x, Fraction) and 
x.denominator == 1 or isinstance(x, float) and x.is_integer()

--
nosy: +tim.peters

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-03 Thread Stefan Krah

Stefan Krah added the comment:

I've been thinking about this, and I'm +1 for the change now.

These structural typing issues for numbers come up regularly
(see also msg257088), and the functions are so simple and
self-explanatory that API-complexity does not really increase.


In general, I understand the argument that Python has become
too complex in some areas -- recently I had to go back to
Python-2.7 in order to understand a certain detail about
.pyc files (in 2.7 it was immediately obvious).


But here I see on such problems.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-01 Thread Robert Smallshire

Robert Smallshire added the comment:

As for whether the shortcut float.is_integer(x) was needed, it has different 
behavior to x==int(x) when x is either NaN or an infinity.  We must even deal 
with two different exception types OverflowError or ValueError respectively for 
these two values on conversion to int. That float.is_integer() simply returns 
False for these values makes it more straightforward to use robustly. The same 
would go for Decimal, which has the same behavior with respect to NaNs and 
infinities as float.

I agree that is_integral may have been a better name, although is_integer has 
the advantage that it avoids conflating numeric values with either of the types 
'int' or 'Integral'.

The motivation for my patches is to converge the interfaces of the various 
number types so that we can simply, and robustly, check for integer values (as 
opposed to integer types) without needing to be concerned about the concrete 
number type, so long as it is Real.  Indeed, this is largely the point of 
having a numeric tower at all.  I am more motivated by usability and concision 
and correctness than efficiency concerns: I believe that where
possible we should allow one number type to be substituted for another, and in 
particular `int` for any other Real type where purely mathematical - rather 
than representational operations - are in play.

Use of the existing float.is_integer is compromised by the fact that people 
have an entirely reasonably habit of passing integers (particularly literals) 
to functions which accept floats which then fail if they use float.is_integer.

Adding this method would reduce the educational load as the various number 
types would be more similar, not less.

I work in industrial fields where computational geometry, and hence rationals, 
floats, infinities and large integers are a day-to-day occurrence. Ultimately, 
I care more about consistency within the numeric tower types (Real, float, int, 
Rational, Integral, Fraction) than I do about Decimal, which is why I separated 
my changes to Decimal into a separate patch.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-04-01 Thread Stefan Krah

Stefan Krah added the comment:

is_integer() is very important for writing new functions. libmpdec has
it and it's used a lot inside mpdecimal.c.


In this case though I assume Robert needs it for duck typing.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread Serhiy Storchaka

Serhiy Storchaka added the comment:

Agree with Raymond.

float.is_integer(x) is more efficient than x==int(x), but is this method used 
anywhere at all? It was added as a part of issue2224.

--
nosy: +christian.heimes, serhiy.storchaka

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread Raymond Hettinger

Raymond Hettinger added the comment:

One other thought:  the name is_integer() is inconsistent with the nomenclature 
in numbers.py.  Had this been included at the outset, its name would have been 
is_integral().

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread Raymond Hettinger

Raymond Hettinger added the comment:

-0 

I question whether we ever needed a short-cut for x==int(x).  Adding this to 
the numeric tower would cause it to propagate broadly including the int type.  
To me, this seems like feature creep resulting in language bloat.  

The decimal module has been around for a long time and no one has ever 
requested the feature.  This suggests it would be just another unused method in 
a module that already has learnability and usability problems due to a fat API.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread SilentGhost

Changes by SilentGhost :


--
components: +Extension Modules
nosy: +facundobatista, mark.dickinson, rhettinger, skrah
stage:  -> patch review
versions: +Python 3.6

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread Robert Smallshire

Robert Smallshire added the comment:

Adding the second patch file.

--
Added file: http://bugs.python.org/file42336/is_integer_decimal.patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue26680] Incorporating float.is_integer into the numeric tower and Decimal

2016-03-31 Thread Robert Smallshire

New submission from Robert Smallshire:

When the useful float.is_integer method was added the opportunity was missed to 
incorporate this method into the numeric tower defined in numbers.py. This 
increased the API distance between different number types, making them less 
substitutable than previously, leading to what might be considered to be absurd 
behaviour:

  >>> a = 5.0
  >>> b = 5
  >>> a.is_integer()
  True
  >>> b.is_integer()
  Traceback (most recent call last):
File "", line 1, in 
  AttributeError: 'int' object has no attribute 'is_integer'

The first attached patch modifies Python to:

 1) Implement int.is_integer() to always return True
 2) Add Real.is_integer() as an abstract method in numbers.py
 3) Provide a default implementation in Rational.is_integer() in numbers.py
 4) Adds tests for is_integer() for int and Fraction.
 5) Documentation changes commensurate with above.

Although the Decimal type deliberately lies outside the numeric tower for 
reasons not relevant here, the principle of least surprise suggests that it too 
should support is_integer().  In fact, the implementation already contains just 
such a function, although it is not exposed to Python.  The second patch 
implements is_integer() for both the pure Python and C implementations of 
Decimal, again with commensurate tests and documentation changes.

I hope these changes can be implemented to reduce the degree of surprise 
encountered when working with different number types in Python.

--
components: Library (Lib)
files: is_integer_numeric_tower.patch
keywords: patch
messages: 262702
nosy: Robert Smallshire2
priority: normal
severity: normal
status: open
title: Incorporating float.is_integer into the numeric tower and Decimal
type: enhancement
Added file: http://bugs.python.org/file42335/is_integer_numeric_tower.patch

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com