On Fri, Mar 6, 2015 at 2:09 PM, Joachim Durchholz <j...@durchholz.org> wrote:
> Hi all,
>
> I've been working on removing C, and now that all the simple cases are done,
> I'm getting to the harder ones - those where SymPy code is called during the
> import (which will fail if the SymPy code being called has not yet fully
> imported).
>
> There's the solvable cases - stuff like ask.py's known-properties database,
> where the initialization can be moved from module-level code to a function,
> so the initialization will happen on demand, after the "import sympy"
> statement has completed.
>
> And now I'm at an unsolvable case: anything that uses S will run class
> initialization code. And replacing that code with something delayed would be
> impractical.
>
> Here's the bottom end of such a stack trace:
>
>   File "sets/fancysets.py", line 173, in <module>
>     class Reals(with_metaclass(Singleton, Interval)):
>   File "core/compatibility.py", line 181, in __new__
>     return meta(name, bases, d)
>   File "core/singleton.py", line 70, in __init__
>     the_instance = ctor(cls)
>   File "sets/fancysets.py", line 176, in __new__
>     return Interval.__new__(cls, -S.Infinity, S.Infinity)
>   File "sets/sets.py", line 744, in __new__
>     if (end < start) == True:
>   File "core/numbers.py", line 1005, in __lt__
>     other = other.evalf()

I think ideally we should avoid calls like this being run at import
time.  To me, this indicates a design issue in the sets.

Aaron Meurer

>   File "core/evalf.py", line 1343, in evalf
>     _create_evalf_table()
>   File "core/evalf.py", line 1184, in _create_evalf_table
>     from sympy.functions.combinatorial.numbers import bernoulli
> ImportError: cannot import name bernoulli
>
> What happens is that the "Reals" class gets initialized, which is a
> Singleton, so its Singleton metaclass runs the constructor to get "the
> instance":
>   File "core/singleton.py", line 70, in __init__
>     the_instance = ctor(cls)
> In the case of Reals, the constructor quite reasonably tries to define th
> set of Reals as the Interval between -Infinity and Infinity. Unfortunately,
> this runs SymPy code during class definition time, which is during import
> time, at which time we can't rely on SymPy being fully available yet. In
> this particular instance, the code runs into _create_evalf_table, but minor
> restructuring could shift the actual point of failure almost anywhere - all
> that's needed is an import that runs some piece of SymPy code that isn't
> imported yet.
>
>
> Question is: WHAT DO WE DO?
> ===========================
>
> 1) What *will* work is to replace the attribute with a function.
> Attributes need to be initialized before use, functions don't need to work
> until they are actually needed.
> Except then S.Foo would have to be rewritten as S.Foo() for all values of
> Foo. Anybody who ever used SymPy and picked up the S.Foo idiom for his code
> will curse us to hell if we do that.
>
> 2) We could defer creation of the_instance. S would first simply collect
> names for its namespace, and trigger instance creation on request (which
> could be done from sympy.__init__.py).
> Any uses of S at import time would fail and need to be fixed (except those
> in the Singleton class constructors). I do not know how many files would be
> affected by that -> not nice, but maybe an option.
>
> 3) We could change the code that accesses the_instance so that actual
> construction is delayed until actual use.
> the_instance is used only inside the __init__ function of Singleton:
>
> class Singleton(ManagedProperties):
>     ...
>     def __init__(cls, name, bases, dict_):
>         ...
>         # The creation call that needs to be delayed:
>         the_instance = ctor(cls)
>         def __new__(cls):
>             # Easy: call ctor(cls) on the first __new__.
>             return the_instance
>         ...
>         # Harder: route S's getattr to a function that
>         # runs ctor(cl) to construct the_instance.
>         setattr(S, name, the_instance)
>
> I don't have a full grasp of what ManagedProperties does yet, so this may or
> may not be doable.
>
>
> Questions? Comments? More ideas how to deal with this?
>
> --
> 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+unsubscr...@googlegroups.com.
> To post to this group, send email to sympy@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/54FA0980.9070304%40durchholz.org.
> For more options, visit https://groups.google.com/d/optout.

-- 
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+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/CAKgW%3D6LUNJBXnxrObzhcTz%3DaLBi9%3Dc0NNqFw05W%2ByKJoPjznEQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to