Highlights of sympy 1.6

69 vistas
Ir al primer mensaje no leído

Oscar Benjamin

no leída,
13 may 2020, 6:09:14 p.m.13/5/20
para sympy
Hi all,

I'm about to put up the release candidate for sympy 1.6. I think that
the release blockers are covered and the performance regressions
identified so far have been addressed. Thanks to all who have helped
with that.

I have been through the release notes and tried to extract what are
the potentially backward incompatible changes in this release and
added them at the top here:
https://github.com/sympy/sympy/wiki/Release-Notes-for-1.6

I'm struggling a bit right now to say what the "highlights" of the
release are. Looking through the notes there are a *lot* of
improvements but it's hard to pull out any coherent big themes. This
would probably be easier if we released more often...

Can anyone offer any suggestions for what sort of things we could list
as highlights? Don't be shy about suggesting your own contributions! I
guess the idea would be to list something that is significant and
perhaps the cumulative output of a number of PRs. Perhaps in
refactoring there are often no release notes for individual PRs but at
the end a major refactor could be considered worth mentioning.

What sort of things might a "user" be interested in from this release?

Oscar

Jason Moore

no leída,
13 may 2020, 6:36:54 p.m.13/5/20
para sympy
I had a look at the backwards incompatibilities.

This one stood out:

Submodule names are no longer imported with from sympy import *. They can still be imported directly like from sympy import core or accessed like sympy.core, or like sys.modules['sympy.simplify'] for modules that share names with SymPy functions.

Is this really necessary? On the face of it, I suspect this could cause a fair amount of code in the wild to break. I'm not sure what breaking this functionality gains, but it surely may cause down stream pain.

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAHVvXxSEkNPjffwqiOA4-8xP0_1D8wAfLVrU9SbnvYSTRZC_Gg%40mail.gmail.com.

David Bailey

no leída,
13 may 2020, 6:39:06 p.m.13/5/20
para sy...@googlegroups.com

Dear Group,

I notice this item in the highlights of 1.6.

DEPRECATION: Passing Poly as the integrand to the integrate function or Integral class is now deprecated. Use the integrate method instead e.g. Poly(x, x).integrate(x)

I do feel a little uneasy about pushing people to use object oriented syntax rather than the integrate function is undesirable. I mean for mathematicians and others who have not come across object oriented programming, I would have thought the dot notation does not come naturally and will confuse because it suggests a product! This notation is also alien to Mathematica, which many will be familiar with.

David

Aaron Meurer

no leída,
13 may 2020, 7:31:53 p.m.13/5/20
para sympy
This fixes a lot of issues like
https://github.com/sympy/sympy/issues/15536 and
https://github.com/sympy/sympy/issues/17626, where it was previously
impossible to reference names in a way you would expect, due to
submodule names that are the same as other submodules or as functions.
Another example is

from sympy import core

or even just

sympy.core

In SymPy 1.5.1, this gives the sub-submodule sympy.core.core. It's
actually difficult to access the submodule sympy.core in SymPy 1.5
(you have to use sys.modules['sympy.core']). In 1.6 it gives
sympy.core, as you would expect.

This shouldn't break much code in the wild because it only affects
import *. Normal imports will continue to work, except for the cases
like above where they will may start giving the more correct thing
(there are still cases where a function has the same name as a module
and you have to use the workaround mentioned in the notes). So for
backwards incompatibility, it primarily affects interactive uses. But
we generally don't want to import submodules in interactive uses,
because it isn't something we want to part of the public API, per se.
For example, I often use expr as a variable name, and having expr
defined by default as sympy.core.expr would sometimes lead to
confusion.

Use of __all__ in __init__.py files is a best practice in Python files
and it's something that we should have been doing a long time ago. It
is also a requirement for our __init__.py files to pass pyflakes
linting, which we now require as part of the CI test suite.

Aaron Meurer
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAP7f1AhwGFHgTC_3qBpjx25W8uydtiuJejnmbpG%3Dk1mtJkFj%2Bw%40mail.gmail.com.

Oscar Benjamin

no leída,
13 may 2020, 7:33:14 p.m.13/5/20
para sympy
On Wed, 13 May 2020 at 23:36, Jason Moore <moore...@gmail.com> wrote:
>
> I had a look at the backwards incompatibilities.
>
> This one stood out:
>
> Submodule names are no longer imported with from sympy import *. They can still be imported directly like from sympy import core or accessed like sympy.core, or like sys.modules['sympy.simplify'] for modules that share names with SymPy functions.
>
> Is this really necessary? On the face of it, I suspect this could cause a fair amount of code in the wild to break. I'm not sure what breaking this functionality gains, but it surely may cause down stream pain.

Some code might break but in future we will have better control of
what is or is not imported and be in a better position to prevent
accidental breakage. The release note emphasises what you might need
to worry about rather than the rationale for the change so I'll
explain that here.

The main change is not that submodules are no longer imported but that
the codebase explicitly lists what is imported from each package using
__all__. This means that imports can never be accidental as they must
be explicitly listed at each chain of package to package import.
Ultimately something is not importable from the top-level sympy
namespace unless it is explicitly listed in __all__ in
sympy/__init__.py.

An example of the kind of report (on github or stackoverflow) that I
have seen is this from sympy 1.5.1:

>>> from sympy import pi, evalf
>>> evalf(pi)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable

(Actually I've just realised this still happens on 1.6 because evalf
is listed in __all__...)

What has happened here is that the sympy.core.evalf module has been
imported unintentionally and appears as the reasonably named function
evalf (why is there no evalf function?). I don't think it was ever
intended that the evalf module would be importable in this way. It's
just a consequence of the fact that in 1.5 sympy/__init__.py uses

from .core import *

and then does not define __all__ itself.

Another example that I have seen reports of is this:

>>> from sympy import core
>>> core
<module 'sympy.core.core' from
'/Users/enojb/current/sympy/sympy/sympy/core/core.py'>

Note that this has imported sympy.core.core rather than sympy.core.

In other cases what is imported depends on which previous imports have occurred:

>>> from sympy import *
>>> stats
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'stats' is not defined
>>> import sympy.stats
>>> from sympy import *
>>> stats
<module 'sympy.stats' from
'/Users/enojb/current/sympy/sympy/sympy/stats/__init__.py'>

Again this is unintentional. Using * import without __all__ has always
been flakey.

So the real change here is not that submodules are removed from
star-import but that star-import is made well defined and
controllable. Since it is now well-defined and controllable we don't
need to allow imports of submodules purely by accident. Of course at
that point we can decide whether we want to list all of the
subpackages in __all__. Since these were only ever there by accident I
decided to remove them.

--
Oscar

Aaron Meurer

no leída,
13 may 2020, 7:33:56 p.m.13/5/20
para sympy
I've noticed in the past as well that it is not always easy to pick
out highlights. Typically the only obvious thing has been completed
GSoC projects. It may be prudent to just remove the section if we
can't find anything obvious to put there. It isn't as necessary as it
used to be since we now actually have complete release notes for all
the changes. In the past we just hand curated changes which were
typically just the biggest ones since it was hard to manually collect
all if them.

Aaron Meurer

David Bailey

no leída,
13 may 2020, 7:34:34 p.m.13/5/20
para sy...@googlegroups.com
On 13/05/2020 23:36, Jason Moore wrote:
I had a look at the backwards incompatibilities.

This one stood out:

Submodule names are no longer imported with from sympy import *. They can still be imported directly like from sympy import core or accessed like sympy.core, or like sys.modules['sympy.simplify'] for modules that share names with SymPy functions.

Is this really necessary? On the face of it, I suspect this could cause a fair amount of code in the wild to break. I'm not sure what breaking this functionality gains, but it surely may cause down stream pain.

I agree strongly with this comment.

There needs to be a simple sway to load all the SymPy functionality - not least because users may not know the exact name of a function they wish to use, let alone what submodule it is located in! In addition, as Jason says, this will break a great deal of code.

Not everyone who wishes to use SymPy is going to be familiar with Python.

David

Aaron Meurer

no leída,
13 may 2020, 7:37:59 p.m.13/5/20
para sympy
> (Actually I've just realised this still happens on 1.6 because evalf
> is listed in __all__...)

Do we have tests for import *? We ought to test that certain things
are not included, like modules or non-sympy objects. It's less
necessary with __all__ and pyflakes checks, but maybe still a good
idea.

Aaron Meurer

Aaron Meurer

no leída,
13 may 2020, 7:40:54 p.m.13/5/20
para sympy
from sympy import * will still work to import all the public functions
and classes. Maybe the release notes are unclear about this. The
change here is that it will no longer include submodule objects, which
are not things that users should ever be using directly (if you want
to access something that isn't included in 'import *', you should
import it directly, like 'from sympy.stats import P').

If this change actually does break something for you please let us
know so we can see if it is something that we hadn't considered.

Aaron Meurer

>
> Not everyone who wishes to use SymPy is going to be familiar with Python.
>
> David
>
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/7a0da02f-b984-b2cc-8bd1-93ad4aa0f687%40dbailey.co.uk.

Oscar Benjamin

no leída,
13 may 2020, 7:43:18 p.m.13/5/20
para sympy
To be clear using `from sympy import *` will still import an enormous
number of functions and other things from all of the different
submodules. What it no longer does is also import the actual submodule
objects from which those functions are defined. The intention of this
change is that most users will not notice the difference.

You can see the full list of what is importable from sympy in 1.6 here:
https://github.com/sympy/sympy/blob/5d1b2c6f04f583ec0beeea4b8238d4151b497332/sympy/__init__.py#L261

--
Oscar

Oscar Benjamin

no leída,
13 may 2020, 8:13:58 p.m.13/5/20
para sympy
Hi David,

Perhaps this is similar to the other thread in that the release note
emphasises what someone should worry about in case their code might
break rather than what the real rationale for the change is.

Poly objects are not something that most users need to use. For
example you can integrate a polynomial like this:

>>> from sympy import Symbol, integrate
>>> x = Symbol('x')
>>> p = x**2 + x
>>> integrate(p, x)
x**3/3 + x**2/2

This integrates a polynomial just fine. The object p here would be
known mathematically as a polynomial but in sympy jargon it is an
instance of Expr rather than of Poly. Poly is a class separate from
Expr that has different methods and behaves in different ways and is
intended to be used in particular contexts where every object is known
to be a polynomial and more general expression classes are
unnecessary.

What has changed in sympy 1.6 is that Poly is no longer a subclass of
Expr and the ways in which Poly and Expr can be interchanged have been
reduced. For example in sympy 1.5.1 you can do:

>>> from sympy import Poly, Symbol, exp
>>> x = Symbol('x')
>>> p = Poly(x**2, x)
>>> p
Poly(x**2, x, domain='ZZ')
>>> p * exp(x)
x**2*exp(x)

What happened here is that we had a Poly but then we multiplied it by
something that couldn't be represented as a Poly because x**2*exp(x)
is not polynomial in x so the result was implicitly converted to an
Expr. Had we multiplied by something else the result might have been a
Poly:

>>> p*x
Poly(x**3, x, domain='ZZ')

So sometimes Poly*Expr gives an Expr and sometimes a Poly. This is not
easy to work with programmatically because Poly and Expr have
completely different methods and attributes.

In SymPy 1.6 Poly and Expr are more clearly separate. The calculation
above will still be the same but will give a warning:

>>> from sympy import Poly, Symbol, exp
>>> x = Symbol('x')
>>> p = Poly(x**2, x)
>>> p * exp(x)
/Users/enojb/current/sympy/sympy/sympy/polys/polytools.py:74:
SymPyDeprecationWarning:
Mixing Poly with non-polynomial expressions in binary operations has
been deprecated since SymPy 1.6. Use the as_expr or as_poly method to
convert types instead. See https://github.com/sympy/sympy/issues/18613
for more info.
SymPyDeprecationWarning(
x**2*exp(x)

This is showing that if you wanted a product like Expr*Expr -> Expr
then you should convert the Poly to Expr first. Otherwise if you
wanted Poly*Poly->Poly then you should convert the Expr to a Poly (and
specify the generator). Methods as_expr and as_poly are provided for
these conversions.

This might seem confusing if you haven't used the Poly class much but
remember that most users have no need to use the Poly class. If you do
want to use the Poly class then it is very useful for certain things.
One example is that integrating a polynomial can be implemented much
more efficiently than integrating a general expression which is why
Poly has an integrate method that can do this for you. So anyone who
is currently using Poly with the integrate function is advised that
the simple fix to their code is to use the Poly.integrate method.

--
Oscar

David Bailey

no leída,
14 may 2020, 3:01:54 a.m.14/5/20
para sy...@googlegroups.com

Well I assumed all along that Poly objects were a much more efficient way of representing  polynomials - presumably an array of tuples of coefficients and exponents where the coefficient is non-zero. If these things are all converted back before the user gets the result, that is just fine. The comparison with Mathematica is interesting, but maybe lead me astray. There there are multiple types of objects (e.g. integers, integer arrays, etc) that behave and display identically to users but have a different internal structures and iner-rconvert silently as required.

David

Oscar Benjamin

no leída,
14 may 2020, 6:27:38 a.m.14/5/20
para sympy
On Thu, 14 May 2020 at 08:01, David Bailey <da...@dbailey.co.uk> wrote:
>
>
> Well I assumed all along that Poly objects were a much more efficient way of representing polynomials - presumably an array of tuples of coefficients and exponents where the coefficient is non-zero. If these things are all converted back before the user gets the result, that is just fine. The comparison with Mathematica is interesting, but maybe lead me astray. There there are multiple types of objects (e.g. integers, integer arrays, etc) that behave and display identically to users but have a different internal structures and iner-rconvert silently as required.

I'm not familiar with Mathematica myself but the way this works in
sympy is that an expression will be converted to Poly internally by
algorithms that need it. For example when calling factor(expr) the
expression will be converted to a Poly and the factorisation algorithm
is performed with the resulting Poly. This happens internally though
so that from the user perspective factor is called with Expr and
returns Expr. The Poly class is available to users for doing efficient
calculations with polynomials but to get the advantages of the
efficient calculations you need to be clear that you are using Poly
and not mix it up with Expr.

This is similar to the way in Python that you need to be careful not
to mix floats into a calculation that involves ints. Provided you
don't input any floats most operations with int will give int. There
is one exception though in Python 3 which is that dividing two ints
gives a float so division is the operation to be careful about. This
is done because in general the ratio of two integers is not an
integer. Sometimes it is an integer but it's important that the type
of the output be predictable so a float is always returned even if the
result could be an int. Likewise with Poly most operations will give
Poly e.g. Poly+Poly->Poly but division will always give Expr:
Poly/Poly->Expr.

--
Oscar

Jason Moore

no leída,
14 may 2020, 1:46:38 p.m.14/5/20
para sympy
These all seem like good reasons to make the change. Did users get a deprecation cycle for the change? i.e. if I mport one of the affected imports in 1.5 I get a deprecation warning?

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Oscar Benjamin

no leída,
14 may 2020, 2:39:05 p.m.14/5/20
para sympy
On Thu, 14 May 2020 at 18:46, Jason Moore <moore...@gmail.com> wrote:
>
> These all seem like good reasons to make the change. Did users get a deprecation cycle for the change? i.e. if I mport one of the affected imports in 1.5 I get a deprecation warning?

No. I'm not sure how you could get a deprecation warning.

For example we would have to make it so that e.g. from sympy import
core still gives the module object for sympy.core.core but wrapped in
some kind of object that gives a deprecation warning when you access
it. Really though from sympy import core should be the expected way to
import the sympy.core package analogous to `import sympy.core as core`
(It would be better if that was the only way to do submodule imports
in Python because it removes this ambiguity).

In SymPy 1.5.1 there are 971 names imported by `from sympy import *`.
In 1.6 there are 874. There have been 8 names added and 105 removed.
The removed names are:

SYMPY_DEBUG add algebras array assumptions basic bivariate boolalg cache
calculus codegen combinatorics common compatibility concrete conditionset
containers contains convolutions core coreerrors cse_main cse_opts curve
decorators dense deprecated deutils discrete ellipse entity epathtools
exceptions expr expr_with_intlimits expr_with_limits expressions exprtools
external factor_ facts fancysets function functions generate geometry gosper
immutable index_methods indexed inequalities inference integrals interactive
line logic manualintegrate matrices meijerint mod mul multidimensional
multinomial multipledispatch ntheory numbers ode operations ordinals parabola
parsing partitions_ pde physics plane plotting point polygon polys polysys
power powerset primetest printing products recurr relational release
residue_ntheory rules sets singleton singularityfunctions solvers sparse
sparsetools strategies summations symbol tensor transforms traversaltools
trigonometry util utilities

Some of these are top-level packages e.g. sympy.physics. I don't see
how we can make "from sympy import *" give something different for
physics than what "from sympy import physics" would give so I can't
see how we could give a deprecation warning for one case but not the
other.

Others are subpackages and submodules e.g. add is there because it is
a top-level module in core and sympy's __init__.py used to do "from
.core import *". Doing "from sympy import add" gives an ImportError in
1.6. We could make "from sympy import add" return a proxy object that
emits a deprecation warning each time you try to access it.

I don't see why anyone should be depending on this though given that
there is no documentation specifying that you can do "from sympy
import add" and no one outside of sympy would be interested in
accessing the add module directly because the significant output from
the module is Add which you can import from sympy directly (and is
documented).

As an side we really should stop putting everything up to the
top-level sympy namespace. There are far too many names there and
importing sympy is slow because it isn't possible without importing
every submodule. A recent bug report pointed out that it takes minutes
to import sympy in brython.

--
Oscar

Jason Moore

no leída,
14 may 2020, 2:57:53 p.m.14/5/20
para sympy
Is it possible to give a blanket deprecation warning if anyone does an import with a `*`? It could warn the user that functionality will change in the next version such that modules are not accessible via star imports.

As more a user than developer of SymPy, I think we should have a very high standard for deprecation. As one of the primary OSS CAS libraries there is a lot of potential code to break in the wild and lots of users to frustrate. From years watching students (as well as myself) get frustrated due to code breaking from software upgrades, I think this is important. We need to be better than Mathematica and Matlab at this to retain and grow users, and they are really really good about not breaking existing code. As developers, these changes may seem trivial, but they are often huge hurdles to users.

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Aaron Meurer

no leída,
14 may 2020, 3:14:30 p.m.14/5/20
para sympy
I agree, and this is why we have a deprecation policy.
https://github.com/sympy/sympy/wiki/Deprecating-policy. In some cases,
it is very difficult to do a deprecation due to technical limitations,
and we just have to make the breaking change, and I think this is an
instance of that.

We also have to balance usability, and improve that where we can, even
if that means breaking API. In this case, if a user uses SymPy in an
interactive way (anything that does "from sympy import *") they will
see things like "add" in the namespace, and might assume that is a
function. But "add" (in SymPy 1.5.1) is a submodule. Furthermore, we
don't want users to use add even as a submodule, because anything on
the "add" module is either a public function that is already in the
public namespace (like Add), or a private function. A big part of
keeping backwards incompatible changes to a minimum is to have a clear
distinction between what is public API and what isn't. That way we can
improve SymPy by refactoring the non-public APIs without breaking
users. This change is an improvement in that direction, since we don't
want submodules to be part of the public API.

Aaron Meurer
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAP7f1AjnrzOEOuk7PNo9sFoO-a4WtJEtN7dUuevLpQEnp7PoKw%40mail.gmail.com.

Oscar Benjamin

no leída,
14 may 2020, 3:23:08 p.m.14/5/20
para sympy
On Thu, 14 May 2020 at 19:57, Jason Moore <moore...@gmail.com> wrote:
>
> Is it possible to give a blanket deprecation warning if anyone does an import with a `*`? It could warn the user that functionality will change in the next version such that modules are not accessible via star imports.

I think that using "from sympy import *" should be fine. We should
stop putting all of the names there and design and document a coherent
way to import things from the different packages but as long as almost
all the functions most users want are at top-level they should be able
to use star import to get them. Many more users would be affected by
deprecating star-import in general than by removing the submodules
from the star import.

If we want to be extra-cautious here then we could do this:

1. Explicitly import all of the packages like sympy.physics that are
implicitly exported in 1.5 and add them to __all__ in
sympy/__init__.py. Those would then continue to be imported by "from
sympy import *".

2. Make a wrapper object for each of the sympy.x.y modules that are
implicitly exported in 1.5 that gives a deprecation warning on access
and add them to __all__ as well. Those would continue to be imported
by "from sympy import *" but would give a warning when used e.g.:

>>> from sympy import *
>>> add.Add
DeprecationWarning: Import the add module as "import sympy.core.add as
add" or "from sympy.core import add" not "from sympy import *" or
"from sympy import add".

--
Oscar

Jason Moore

no leída,
14 may 2020, 3:33:35 p.m.14/5/20
para sympy
> A big part of  keeping backwards incompatible changes to a minimum is to have a clear
distinction between what is public API and what isn't.

Maybe we should start being more careful about naming things with preprended underscores, letting that explicitly define what is and isn't public. This could be applied to module names, module level variables, etc. I think it is implicit that anything without leading underscores is public API and that things with leading underscores that are documented like public things are public.

Oscar, your idea looks helpful. It would resolve my concerns, but I'm not sure how to evaluate if that is worth doing. My opinion is that if the effort to deprecate isn't extreme, then we should do it. What "extreme" is defined as, is certainly debatable.

Jason


--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Oscar Benjamin

no leída,
14 may 2020, 3:33:45 p.m.14/5/20
para sympy
Similar considerations potentially apply to other packages as well.
The __all__ attribute was added to 50 out of 138 __init__.py files
that didn't already have it. Obviously the top-level __init__.py is
the most significant though.

Aaron Meurer

no leída,
14 may 2020, 4:12:28 p.m.14/5/20
para sympy
> Oscar, your idea looks helpful. It would resolve my concerns, but I'm not sure how to evaluate if that is worth doing. My opinion is that if the effort to deprecate isn't extreme, then we should do it. What "extreme" is defined as, is certainly debatable.

I may be wrong on this, but I don't think Oscar's idea would actually
work. The issue is that there's no way to tell the difference between

from sympy import *
core

and

from sympy import core
core

where the latter still works and should work. We could make it not
work, but it's expected Python behavior to be able to import
submodules like this.

__all__ only affects import *, not explicit imports. To be sure, the
change in SymPy does remove some sub-submodules from the top level
(like "from sympy import add"), due to the fact that we no longer use
import * in the __init__.py files themselves.

(side comment: I think that it's a design mistake in Python that
submodules can be imported the same as explicitly exported names like
this. It creates a lot of potential confusion with relatively little
benefit. There are some technical reasons why it happens as well as
some instances where it is necessary, but it's by and large a bad
feature in my opinion.

Aaron Meurer

Oscar Benjamin

no leída,
14 may 2020, 6:45:13 p.m.14/5/20
para sympy
On Thu, 14 May 2020 at 21:12, Aaron Meurer <asme...@gmail.com> wrote:
>
> > Oscar, your idea looks helpful. It would resolve my concerns, but I'm not sure how to evaluate if that is worth doing. My opinion is that if the effort to deprecate isn't extreme, then we should do it. What "extreme" is defined as, is certainly debatable.
>
> I may be wrong on this, but I don't think Oscar's idea would actually
> work. The issue is that there's no way to tell the difference between
>
> from sympy import *
> core
>
> and
>
> from sympy import core
> core
>
> where the latter still works and should work. We could make it not
> work, but it's expected Python behavior to be able to import
> submodules like this.

I've opened a PR:
https://github.com/sympy/sympy/pull/19316

The PR adds back all the submodules wrapped in an object that emits a
warning when accessed e.g.:

In [1]: from sympy import add

In [2]: add.Add
/Users/enojb/current/sympy/sympy/sympy/__init__.py:653: SymPyDeprecationWarning:
importing sympy.core.add with 'from sympy import *' has been
deprecated since SymPy 1.6. Use import sympy.core.add instead. See
https://github.com/sympy/sympy/issues/18245 for more info.

deprecated_since_version="1.6").warn()
Out[2]: sympy.core.add.Add

I left out core which can not be included in a backward compatible way
without failing to fix the broken behaviour that from sympy import
core doesn't give the package.

This is similar to what scipy recently did:
https://github.com/scipy/scipy/pull/10290

Top-level packages like printing, polys etc are all just listed in
__all__ (and not deprecated).

The only names not importable by from sympy import * in the PR that
were previously importable in 1.5 are:

SYMPY_DEBUG
core
physics

Those could also be added. In the case of core the reason is above.
For physics it's because adding it means importing it even during a
plain "import sympy" which otherwise wouldn't happen. SYMPY_DEBUG
seems obviously internal to me.

--
Oscar

Jason Moore

no leída,
14 may 2020, 8:37:12 p.m.14/5/20
para sympy
Thanks Oscar. I'll look at it later tonight to give you a review.

Jason

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.

Oscar Benjamin

no leída,
17 may 2020, 10:05:22 a.m.17/5/20
para sympy
I'm going to push a second release candidate with this change and also
the fix for this:
https://github.com/sympy/sympy/issues/19326

Another import issue has occurred to me though which is that the ode
module has now become a package so the ode.py file was moved from
sympy/solvers/ode.py to sympy/solvers/ode/ode.py. The "public" names
(as documented) are imported into sympy/solvers/ode/__init__.py but
these are a small subset of the total names available when doing

from sympy.solvers.ode import *

This doesn't just apply to star-imports and __all__ because someone
might be doing something like:

from sympy.solvers.ode import solve_ics

even though constant_simp is not listed as a "user" function in the
documentation:
https://docs.sympy.org/latest/modules/solvers/ode.html

Attempting to import solve_ics like that will give an ImportError in 1.6.

Most of the things importable from the ode module are actually from
other places in sympy and are just used internally in the module. Some
of the things are defined in the ode module and are not importable
from anywhere else. Most of those are internal functions that are not
really usable outside of dsolve but there are some that someone might
want to use e.g. checksysodesol, classify_sysode, solve_ics...

The full list of names that is importable from the ode module in 1.5.1
but not from the ode package in 1.6 is:

Add
And
AppliedUndef
AtomicExpr
BooleanAtom
BooleanFalse
BooleanTrue
Derivative
Dummy
Eq
Equality
Expr
Function
I
Integral
Matrix
Mul
NaN
Not
Number
Order
Piecewise
Poly
PolynomialError
Pow
Rational
RootOf
S
Subs
Symbol
Tuple
Wild
airyai
airybi
atan2
besselj
besselsimp
bessely
cancel
cbrt
check_linear_2eq_order1
check_linear_2eq_order2
check_linear_3eq_order1
check_linear_neq_order1
check_nonlinear_2eq_order1
check_nonlinear_2eq_order2
check_nonlinear_3eq_order1
check_nonlinear_3eq_order2
checksol
checksysodesol
classify_sysode
collect
collect_const
conjugate
constant_renumber
cos
cse
default_sort_key
defaultdict
degree
diff
div
division
equivalence
equivalence_hypergeometric
exp
expand
expand_mul
eye
factor_terms
factorial
fraction
gcd
get_numbered_constants
hyper
im
integrate
is_sequence
islice
iter_numbered_constants
iterable
lcm
lie_heuristic_abaco1_product
lie_heuristic_abaco1_simple
lie_heuristic_abaco2_similar
lie_heuristic_abaco2_unique_general
lie_heuristic_abaco2_unique_unknown
lie_heuristic_bivariate
lie_heuristic_chi
lie_heuristic_function_sum
lie_heuristic_linear
lie_heuristics
log
logcombine
match_2nd_2F1_hypergeometric
match_2nd_hypergeometric
match_2nd_linear_bessel
numbered_symbols
ode_1st_exact
ode_1st_homogeneous_coeff_best
ode_1st_homogeneous_coeff_subs_dep_div_indep
ode_1st_homogeneous_coeff_subs_indep_div_dep
ode_1st_linear
ode_1st_power_series
ode_2nd_hypergeometric
ode_2nd_linear_airy
ode_2nd_linear_bessel
ode_2nd_power_series_ordinary
ode_2nd_power_series_regular
ode_Bernoulli
ode_Liouville
ode_Riccati_special_minus2
ode_almost_linear
ode_factorable
ode_lie_group
ode_linear_coefficients
ode_nth_algebraic
ode_nth_linear_constant_coeff_homogeneous
ode_nth_linear_constant_coeff_undetermined_coefficients
ode_nth_linear_constant_coeff_variation_of_parameters
ode_nth_linear_euler_eq_homogeneous
ode_nth_linear_euler_eq_nonhomogeneous_undetermined_coefficients
ode_nth_linear_euler_eq_nonhomogeneous_variation_of_parameters
ode_nth_order_reducible
ode_order
ode_separable
ode_separable_reduced
ode_sol_simplicity
odesimp
oo
ordered
pdsolve
posify
powdenest
powsimp
print_function
range
re
rootof
roots
roots_quartic
separatevars
series
sift
simplify
sin
solve
solve_ics
sqrt
string_types
sub_func_doit
symbols
sympify
sysode_linear_2eq_order1
sysode_linear_2eq_order2
sysode_linear_3eq_order1
sysode_linear_neq_order1
sysode_nonlinear_2eq_order1
sysode_nonlinear_3eq_order1
tan
terms_gcd
trigsimp
vectorize
wronskian
zeros
zoo


--
Oscar
> To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAP7f1AjefdtOi1qpitdJmL5snooWdOjwqczVLu%3D1Xpzy%2BhA7cQ%40mail.gmail.com.
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos