Example #1
0
def cython_compile(code, **kwds):
    """
    Given a block of Cython code (as a text string), this function
    compiles it using a C compiler, and includes it into the global
    namespace.

    AUTHOR: William Stein, 2006-10-31

    .. WARNING::

        Only use this from Python code, not from extension code, since
        from extension code you would change the global scope (i.e.,
        of the Sage interpreter). And it would be stupid, since you're
        already writing Cython!

        Also, never use this in the standard Sage library.  Any code
        that uses this can only run on a system that has a C compiler
        installed, and we want to avoid making that assumption for
        casual Sage usage.  Also, any code that uses this in the
        library would greatly slow down startup time, since currently
        there is no caching.

    .. TODO::

        Need to create a clever caching system so code only gets
        compiled once.
    """
    tmpfile = tmp_filename(ext=".pyx")
    with open(tmpfile,'w') as f:
        f.write(code)
    return cython_import_all(tmpfile, get_globals(), **kwds)
Example #2
0
def cython_compile(code, **kwds):
    """
    Given a block of Cython code (as a text string), this function
    compiles it using a C compiler, and includes it into the global
    namespace.

    AUTHOR: William Stein, 2006-10-31

    .. WARNING::

        Only use this from Python code, not from extension code, since
        from extension code you would change the global scope (i.e.,
        of the Sage interpreter). And it would be stupid, since you're
        already writing Cython!

        Also, never use this in the standard Sage library.  Any code
        that uses this can only run on a system that has a C compiler
        installed, and we want to avoid making that assumption for
        casual Sage usage.  Also, any code that uses this in the
        library would greatly slow down startup time, since currently
        there is no caching.

    .. TODO::

        Need to create a clever caching system so code only gets
        compiled once.
    """
    tmpfile = tmp_filename(ext=".pyx")
    with open(tmpfile, 'w') as f:
        f.write(code)
    return cython_import_all(tmpfile, get_globals(), **kwds)
Example #3
0
    def eval(self, s, locals=None):
        r"""
        Evaluate embedded <sage> tags

        INPUT:

        - ``s`` -- string.

        - ``globals`` -- dictionary. The global variables when
          evaluating ``s``. Default: the current global variables.

        OUTPUT:
     
        A :class:`HtmlFragment` instance.
     
        EXAMPLES::

            sage: a = 123
            sage: html.eval('<sage>a</sage>')
            <script type="math/tex">123</script>
            sage: html.eval('<sage>a</sage>', locals={'a': 456})
            <script type="math/tex">456</script>
        """
        if hasattr(s, '_html_'):
            deprecation(
                18292,
                'html.eval() is for strings, use html() for sage objects')
            return s._html_()
        if locals is None:
            from sage.repl.user_globals import get_globals
            locals = get_globals()
        s = str(s)
        s = math_parse(s)
        t = ''
        while len(s) > 0:
            i = s.find('<sage>')
            if i == -1:
                t += s
                break
            j = s.find('</sage>')
            if j == -1:
                t += s
                break
            t += s[:i] + '<script type="math/tex">%s</script>'%\
                     latex(sage_eval(s[6+i:j], locals=locals))
            s = s[j + 7:]
        return HtmlFragment(t)
Example #4
0
File: html.py Project: Babyll/sage
    def eval(self, s, locals=None):
        r"""
        Evaluate embedded <sage> tags

        INPUT:

        - ``s`` -- string.

        - ``globals`` -- dictionary. The global variables when
          evaluating ``s``. Default: the current global variables.

        OUTPUT:
     
        A :class:`HtmlFragment` instance.
     
        EXAMPLES::

            sage: a = 123
            sage: html.eval('<sage>a</sage>')
            <script type="math/tex">123</script>
            sage: html.eval('<sage>a</sage>', locals={'a': 456})
            <script type="math/tex">456</script>
        """
        if hasattr(s, '_html_'):
            deprecation(18292, 'html.eval() is for strings, use html() for sage objects')
            return s._html_()
        if locals is None:
            from sage.repl.user_globals import get_globals
            locals = get_globals()
        s = str(s)
        s = math_parse(s)
        t = ''
        while len(s) > 0:
            i = s.find('<sage>')
            if i == -1:
                 t += s
                 break
            j = s.find('</sage>')
            if j == -1:
                 t += s
                 break
            t += s[:i] + '<script type="math/tex">%s</script>'%\
                     latex(sage_eval(s[6+i:j], locals=locals))
            s = s[j+7:]
        return HtmlFragment(t)
Example #5
0
    def get_value(self):
        """
        Evaluate the bare widget value using :func:`sage_eval`.

        EXAMPLES::

            sage: from ipywidgets import Dropdown
            sage: from sage.repl.ipython_kernel.widgets import EvalWidget
            sage: class EvalDropdown(EvalWidget, Dropdown): pass
            sage: w = EvalDropdown(options=["the_answer"], transform=RR)
            sage: w
            EvalDropdown(options=('the_answer',), value='the_answer')
            sage: the_answer = 42
            sage: w.get_value()
            42
            sage: w.get_interact_value()
            42.0000000000000
        """
        return sage_eval(self.value, get_globals())
Example #6
0
    def get_value(self):
        """
        Evaluate the bare widget value using :func:`sage_eval`.

        EXAMPLES::

            sage: from ipywidgets import Dropdown
            sage: from sage.repl.ipython_kernel.widgets import EvalWidget
            sage: class EvalDropdown(EvalWidget, Dropdown): pass
            sage: w = EvalDropdown(options=["the_answer"], transform=RR)
            sage: w
            EvalDropdown(options=('the_answer',), value='the_answer')
            sage: the_answer = 42
            sage: w.get_value()
            42
            sage: w.get_interact_value()
            42.0000000000000
        """
        return sage_eval(self.value, get_globals())
Example #7
0
    def eval(self, s, locals=None):
        r"""
        Evaluate embedded <sage> tags

        INPUT:

        - ``s`` -- string.

        - ``globals`` -- dictionary. The global variables when
          evaluating ``s``. Default: the current global variables.

        OUTPUT:

        A :class:`HtmlFragment` instance.

        EXAMPLES::

            sage: a = 123
            sage: html.eval('<sage>a</sage>')
            \(123\)
            sage: html.eval('<sage>a</sage>', locals={'a': 456})
            \(456\)
        """
        if locals is None:
            from sage.repl.user_globals import get_globals
            locals = get_globals()
        s = str(s)
        s = math_parse(s)
        t = ''
        while s:
            i = s.find('<sage>')
            if i == -1:
                t += s
                break
            j = s.find('</sage>')
            if j == -1:
                t += s
                break
            t += s[:i] + r'\({}\)'.format(
                latex(sage_eval(s[6 + i:j], locals=locals)))
            s = s[j + 7:]
        return HtmlFragment(t)
Example #8
0
    def eval(self, x, globals=None, locals=None):
        """
        Compile fortran code ``x`` and adds the functions in it to
        ``globals``.

        INPUT:

        - ``x`` -- Fortran code

        - ``globals`` -- a dict to which to add the functions from the
          fortran module

        - ``locals`` -- ignored

        EXAMPLES::

            sage: code = '''
            ....: C FILE: FIB1.F
            ....:       SUBROUTINE FIB(A,N)
            ....: C
            ....: C     CALCULATE FIRST N FIBONACCI NUMBERS
            ....: C
            ....:       INTEGER N
            ....:       REAL*8 A(N)
            ....:       DO I=1,N
            ....:          IF (I.EQ.1) THEN
            ....:             A(I) = 0.0D0
            ....:          ELSEIF (I.EQ.2) THEN
            ....:             A(I) = 1.0D0
            ....:          ELSE
            ....:             A(I) = A(I-1) + A(I-2)
            ....:          ENDIF
            ....:       ENDDO
            ....:       END
            ....: C END FILE FIB1.F
            ....: '''
            sage: fortran(code, globals())
            sage: import numpy
            sage: a = numpy.array(range(10), dtype=float)
            sage: fib(a, 10)
            sage: a
            array([  0.,   1.,   1.,   2.,   3.,   5.,   8.,  13.,  21.,  34.])

        TESTS::

            sage: os.chdir(DOT_SAGE)
            sage: fortran.eval("SYNTAX ERROR !@#$")
            Traceback (most recent call last):
            ...
            RuntimeError: failed to compile Fortran code:...
            sage: os.getcwd() == os.path.realpath(DOT_SAGE)
            True
        """
        if globals is None:
            globals = self.globs
            if globals is None:
                from sage.repl.user_globals import get_globals
                globals = get_globals()

        # Create everything in a temporary directory
        mytmpdir = tmp_dir()

        try:
            old_cwd = os.getcwd()
            os.chdir(mytmpdir)

            name = "fortran_module"  # Python module name
            # if the first line has !f90 as a comment, gfortran will
            # treat it as Fortran 90 code
            if x.startswith('!f90'):
                fortran_file = name + '.f90'
            else:
                fortran_file = name + '.f'

            s_lib_path = ['-L' + p for p in self.library_paths]
            s_lib = ['-l' + l for l in self.libraries]

            with open(fortran_file, 'w') as fobj:
                fobj.write(x)

            # This is basically the same as what f2py.compile() does, but we
            # do it manually here in order to customize running the subprocess
            # a bit more (in particular to capture stderr)
            cmd = [
                sys.executable, '-c', 'import numpy.f2py; numpy.f2py.main()'
            ]

            # What follows are the arguments to f2py itself (appended later
            # just for logical separation)
            cmd += [
                '-c', '-m', name, fortran_file, '--quiet',
                '--f77exec=sage-inline-fortran',
                '--f90exec=sage-inline-fortran'
            ] + s_lib_path + s_lib

            try:
                out = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            except subprocess.CalledProcessError as exc:
                raise RuntimeError(
                    "failed to compile Fortran code:\n{}".format(exc.output))

            # Note that f2py() doesn't raise an exception if it fails.
            # In that case, the import below will fail.
            try:
                mod = _import_module_from_path(name, [mytmpdir])
            except ImportError as exc:
                # Failed to import the module; include any output from building
                # the module (even though it was ostensibly successful) in case
                # it might help
                msg = "failed to load compiled Fortran code: {}".format(exc)
                if out:
                    msg += '\n' + out
                raise RuntimeError(msg)

            if self.verbose:
                print(out)
        finally:
            os.chdir(old_cwd)

            if sys.platform != 'cygwin':
                # Do not delete temporary DLLs on Cygwin; this will cause
                # future forks of this process to fail.  Instead temporary DLLs
                # will be cleaned up upon process exit
                try:
                    shutil.rmtree(mytmpdir)
                except OSError:
                    # This can fail for example over NFS
                    pass

        for k, x in mod.__dict__.items():
            if k[0] != '_':
                globals[k] = x
Example #9
0
    def eval(self, x, globals=None, locals=None):
        """
        Compile fortran code ``x`` and adds the functions in it to
        ``globals``.

        INPUT:

        - ``x`` -- Fortran code

        - ``globals`` -- a dict to which to add the functions from the
          fortran module

        - ``locals`` -- ignored

        EXAMPLES::

            sage: code = '''
            ....: C FILE: FIB1.F
            ....:       SUBROUTINE FIB(A,N)
            ....: C
            ....: C     CALCULATE FIRST N FIBONACCI NUMBERS
            ....: C
            ....:       INTEGER N
            ....:       REAL*8 A(N)
            ....:       DO I=1,N
            ....:          IF (I.EQ.1) THEN
            ....:             A(I) = 0.0D0
            ....:          ELSEIF (I.EQ.2) THEN
            ....:             A(I) = 1.0D0
            ....:          ELSE
            ....:             A(I) = A(I-1) + A(I-2)
            ....:          ENDIF
            ....:       ENDDO
            ....:       END
            ....: C END FILE FIB1.F
            ....: '''
            sage: fortran(code, globals())
            sage: import numpy
            sage: a = numpy.array(range(10), dtype=float)
            sage: fib(a, 10)
            sage: a
            array([  0.,   1.,   1.,   2.,   3.,   5.,   8.,  13.,  21.,  34.])

        TESTS::

            sage: os.chdir(SAGE_ROOT)
            sage: fortran.eval("SYNTAX ERROR !@#$")
            Traceback (most recent call last):
            ...
            RuntimeError: failed to compile Fortran code:...
            sage: os.getcwd() == SAGE_ROOT
            True
        """
        if globals is None:
            globals = self.globs
            if globals is None:
                from sage.repl.user_globals import get_globals
                globals = get_globals()

        from numpy import f2py

        # Create everything in a temporary directory
        mytmpdir = tmp_dir()

        try:
            old_cwd = os.getcwd()
            os.chdir(mytmpdir)

            name = "fortran_module"  # Python module name
            # if the first line has !f90 as a comment, gfortran will
            # treat it as Fortran 90 code
            if x.startswith('!f90'):
                fortran_file = name + '.f90'
            else:
                fortran_file = name + '.f'

            s_lib_path = ""
            s_lib = ""
            for s in self.library_paths:
                s_lib_path = s_lib_path + "-L%s "

            for s in self.libraries:
                s_lib = s_lib + "-l%s "%s

            log = name + ".log"
            extra_args = ('--quiet --f77exec=sage-inline-fortran '
                          '--f90exec=sage-inline-fortran {lib_path} {lib} '
                          '> {log} 2>&1'.format(lib_path=s_lib_path,
                                                lib=s_lib, log=log))

            f2py.compile(x, name, extra_args=extra_args,
                         source_fn=fortran_file)

            with open(log) as fobj:
                log_string = fobj.read()

            # Note that f2py() doesn't raise an exception if it fails.
            # In that case, the import below will fail.
            try:
                mod = _import_module_from_path(name, [mytmpdir])
            except ImportError:
                raise RuntimeError("failed to compile Fortran code:\n" +
                                   log_string)

            if self.verbose:
                print(log_string)
        finally:
            os.chdir(old_cwd)

            if sys.platform != 'cygwin':
                # Do not delete temporary DLLs on Cygwin; this will cause
                # future forks of this process to fail.  Instead temporary DLLs
                # will be cleaned up upon process exit
                try:
                    shutil.rmtree(mytmpdir)
                except OSError:
                    # This can fail for example over NFS
                    pass

        for k, x in iteritems(mod.__dict__):
            if k[0] != '_':
                globals[k] = x