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