Skip to content

Conversation

@parkereberry1923
Copy link
Contributor

@parkereberry1923 parkereberry1923 commented Apr 15, 2019

References to other Issues or PRs

Fixes #12134

Brief description of what is fixed or changed

  • Number inherits from numbers.Number
  • Float inherits from numbers.Real
  • Rational inherits from numbers.Rational
  • Defined __floor__() and __ceil__() for Number, Float, and Rational
  • Defined numerator() and denominator() for Rational

Other comments

  • If we want Integer to inherit from numbers.Integral, we need bit-string operators: '<<', '>>', '|', '&', '^', and '~'.

Release Notes

  • core
    • isinstance for Python numeric ABCs now works for the basic SymPy number types.

@sympy-bot
Copy link

sympy-bot commented Apr 15, 2019

Hi, I am the SymPy bot (v147). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.5.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

Click here to see the pull request description that was parsed.

<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->
Fixes #12134


#### Brief description of what is fixed or changed
- Number inherits from numbers.Number
- Float inherits from numbers.Real
- Rational inherits from numbers.Rational
- Defined \_\_floor\_\_() and \_\_ceil\_\_() for Number, Float, and Rational
- Defined numerator() and denominator() for Rational

#### Other comments
- If we want Integer to inherit from numbers.Integral, we need bit-string operators: '<<', '>>', '|', '&', '^', and '~'.

#### Release Notes
<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* core
  * `isinstance` for Python numeric ABCs now works for the basic SymPy number types.
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

Copy link
Member

@Sc0rpi0n101 Sc0rpi0n101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch fails the build tests.
Not sure why #33122.12 failed

But you can try my suggestions and see if the tests pass


import mpmath
import mpmath.libmp as mlib
import numbers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import numbers
import numbers as num

You might want to import it as num since you are working in a module of the same name

pass

class Number(AtomicExpr):
class Number(with_metaclass(ManagedABCMetaclass, AtomicExpr, numbers.Number)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try if this passes the tests

Suggested change
class Number(with_metaclass(ManagedABCMetaclass, AtomicExpr, numbers.Number)):
class Number(with_metaclass(ManagedABCMetaclass, AtomicExpr, num.Number)):

Maybe the build errors are because python thinks you are referencing sympy.code.number.Numbers inside the definition of the same, so the module cannot have Number as it is not defined yet.



class Float(Number):
class Float(with_metaclass(ManagedABCMetaclass, Number, numbers.Real)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class Float(with_metaclass(ManagedABCMetaclass, Number, numbers.Real)):
class Float(with_metaclass(ManagedABCMetaclass, Number, num.Real)):

Same here



class Rational(Number):
class Rational(with_metaclass(ManagedABCMetaclass, Number, numbers.Rational)):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class Rational(with_metaclass(ManagedABCMetaclass, Number, numbers.Rational)):
class Rational(with_metaclass(ManagedABCMetaclass, Number, num.Rational)):

And here

@sylee957 sylee957 added the core label Apr 15, 2019
@codecov
Copy link

codecov bot commented Apr 15, 2019

Codecov Report

Merging #16652 into master will increase coverage by 0.061%.
The diff coverage is 95%.

@@             Coverage Diff              @@
##           master    #16652       +/-   ##
============================================
+ Coverage   73.79%   73.852%   +0.061%     
============================================
  Files         619       619               
  Lines      159222    159591      +369     
  Branches    37366     37454       +88     
============================================
+ Hits       117491    117862      +371     
+ Misses      36297     36272       -25     
- Partials     5434      5457       +23

@Sc0rpi0n101
Copy link
Member

>>> import numbers as nums
>>> nums.Number
<class 'numbers.Number'>
>>> class abc(nums.Number):
...     print ("hello")
... 
hello

How is the build getting an attribute error?
Number is a part of the module

well, you can try from numbers import Number as nums to see if that if that works

@shivanikohlii
Copy link
Contributor

well, you can try from numbers import Number as nums to see if that works
Is there a way we can locally test these changes?

@Sc0rpi0n101
Copy link
Member

Is there a way we can locally test these changes?

Well, I tested the module core and it passed the tests.
I am running a full test for sympy. I will inform you if it fails.

For testing in sympy, you can check:
https://docs.sympy.org/latest/modules/utilities/runtests.html
https://github.com/sympy/sympy/wiki/Running-tests

or you can use pytest

@shivanikohlii
Copy link
Contributor

I am running a full test for sympy. I will inform you if it fails.
I ran the test suite locally and it compiled without errors but is failing during integration.

@Sc0rpi0n101
Copy link
Member

Sc0rpi0n101 commented Apr 15, 2019

tests finished: 8166 passed, 226 skipped, 354 expected to fail, 2 expected to fail but passed,
in 2253.24 seconds
Yeah, passed for my system too

Actually the tests didn't even start for the fails, the build failed before that.
Don't know why Travis is failing the build

@Sc0rpi0n101
Copy link
Member

Was Number not in python 2.7?
All the fails are 2.7 or pypy.
All 3.5 are passing?

@shivanikohlii
Copy link
Contributor

Don't know why Travis is failing the build

Maybe @sylee957 might know what's causing it to fail.

Numbers existed in 2.7

@Sc0rpi0n101
Copy link
Member

Yeah, the 2.7 docs have numbers.Number as a base class.
Odd

Copy link
Member

@Sc0rpi0n101 Sc0rpi0n101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you try changing these and see if that work.

>>> from sympy import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "sympy/__init__.py", line 57, in <module>
    from .core import *
  File "sympy/core/__init__.py", line 8, in <module>
    from .expr import Expr, AtomicExpr, UnevaluatedExpr
  File "sympy/core/expr.py", line 3616, in <module>
    from .mul import Mul
  File "sympy/core/mul.py", line 1805, in <module>
    from .numbers import Rational
  File "sympy/core/numbers.py", line 492, in <module>
    class Number(with_metaclass(ManagedABCMetaclass, AtomicExpr, nums.Number)):
AttributeError: 'module' object has no attribute 'Number'

I'm getting this in 2.7 on my machine too, did not get it in 3.7
Might be that using nums.Number in class definition was not supported. Not sure.

You can accept the changes in the review itself if it saves some time,
or we can wait for sylee


import mpmath
import mpmath.libmp as mlib
import numbers as nums
Copy link
Member

@Sc0rpi0n101 Sc0rpi0n101 Apr 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import numbers as nums
from sympy.external import import_module
nums = import_module('numbers')

@asmeurer
Copy link
Member

I think it would be better to register the classes with the abcs, similar to how numpy does it, rather than directly subclassing.

I'm not sure about bitwise operations. It could cause confusion with the logic operations that are defined for those operators. We do currently raise a TypeError when numbers other than 0 or 1 are used with boolean functions, so it isn't strictly an issue. See also #5353.

@sylee957
Copy link
Member

sylee957 commented Apr 16, 2019

I think the reason of python 2 failing, is that

import numbers as nums

looking up the module sympy.core.numbers instead of python builtin package.

You can inspect what's going on, if you use print(help(nums)) anywhere in the file.

Adding from __future__ import absolute_import may help,
or you may use

from sympy.external import import_module
nums = import_module('numbers')

or anything you can use to load correct module.

Though I have not much knowledge, about the idea from @asmeurer though.

@Sc0rpi0n101
Copy link
Member

Sc0rpi0n101 commented Apr 16, 2019

from sympy.external import import_module
nums = import_module('numbers')

Thanks, @sylee957
It did work locally for both python 2 and 3.
The import was successful and the tests also passed.

Still, have to see if it works for Travis

@Sc0rpi0n101
Copy link
Member

This time one of the build tests failed due to HTTP error.
Unfortunate.
Can you restart the build?

@asmeurer
Copy link
Member

If we do go with subclassing instead of adding them to the list externally, we should determine if there is any performance impact (see https://github.com/sympy/sympy_benchmarks).

@shivanikohlii
Copy link
Contributor

we should determine if there is any performance impact (see https://github.com/sympy/sympy_benchmarks).

How can we do that?

@asmeurer
Copy link
Member

Apparently we need instructions in the README for that repo. You should set up asv and compare the results against master and this branch.

@shivanikohlii
Copy link
Contributor

You should set up asv and compare the results against master and this branch.

I'm a little confused about how to use asv to check performance. I'm cloning sympy_benchmark and using that?

@asmeurer
Copy link
Member

Yes. You'll need to edit the json file to change the repo from "repo": "https://github.com/sympy/sympy.git", to the path to your local checkout. Then you can do asv compare master Issue-12134-Python-Numbers-ABC.

@shivanikohlii
Copy link
Contributor

asv compare master Issue-12134-Python-Numbers-ABC
>Did not find results for commit 54b108d354fe22023dccfca9a7f44c38b39a9881

I can't find this commit in our commit history, I'm not sure why asv compare master Issue-12134-Python-Numbers-ABC is looking for it. Is there a specific place I should be looking?

@asmeurer
Copy link
Member

You have to run asv run -s 1 master and asv run -s 1 Issue-12134-Python-Numbers-ABC first so it can benchmark it. The asv syntax is a bit confusing. The README on the benchmarks page should be updated for this case. I wish asv would just run the benchmarks automatically when they aren't found.

Also, instead of master I would recommend using asv run -s1 54b108d354fe22023dccfca9a7f44c38b39a9881, the master commit that this was based on (for you, they are the same because you haven't pulled yet, but once you git pull the master branch they won't be). That way the benchmarks won't be affected by any unrelated changes that have been merged into master since you made this branch.

@shivanikohlii
Copy link
Contributor

Thanks @asmeurer, that worked!

I guess it might make more sense to add them to the list externally instead of subclassing. What do you guys think?
image
image
image
image

@asmeurer
Copy link
Member

I think it makes sense.

@shivanikohlii
Copy link
Contributor

@asmeurer we did the register thing like numpy. Does this look good to go?

@asmeurer
Copy link
Member

asmeurer commented May 1, 2019

Can you add tests that the numbers ABCs work (like assert isinstance(Float(1.1), Real) and so on).

@sylee957
Copy link
Member

sylee957 commented May 4, 2019

I wonder how the new implementation improves the performance. Do you have any benchmark result?

@shivanikohlii
Copy link
Contributor

shivanikohlii commented May 5, 2019

Do you have any benchmark result?

Yes, no decline in performance -
image
image
image

@shivanikohlii
Copy link
Contributor

@sylee957 is there anything else we need to do for this PR?

nums.Rational.register(Rational)
nums.Rational.register(Integer)

_register_classes();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the semicolon from the end of the line.

from sympy.core.cache import lru_cache

from sympy.external import import_module
nums = import_module('numbers')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this isn't just import numbers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it fails on 2.7 due to name collision.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. I think it should work if you add absolute_import to the __future__ import at the top of the file.

@asmeurer
Copy link
Member

asmeurer commented May 8, 2019

A couple of minor comments. The rest looks good.

@shivanikohlii
Copy link
Contributor

@asmeurer Done! Thank you for telling me about the import fix.

@asmeurer
Copy link
Member

asmeurer commented May 9, 2019

Thank you. This looks good now. I updated the release notes since we aren't literally subclassing anymore.

@asmeurer asmeurer merged commit 09786a1 into sympy:master May 9, 2019
@shivanikohlii shivanikohlii deleted the Issue-12134-Python-Numbers-ABC branch May 9, 2019 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sympy numbers don't adhere to Python's numbers ABC

7 participants