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()
  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.

Reply via email to