def is_jvm_available(self): """ Returns True if the Java Virtual Machine is available and False if not. EXAMPLES: Check that it returns a boolean:: sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() sage: type(JData.is_jvm_available()) <type 'bool'> """ #scratch file for Jmol errors and status jmolscratch = os.path.join(DOT_SAGE, "sage_notebook.sagenb", "jmol_scratch") if not os.path.exists(jmolscratch): sage_makedirs(jmolscratch) scratchout = os.path.join(jmolscratch,"jmolout.txt") jout=open(scratchout,'w') testjavapath = os.path.join(SAGE_LOCAL, "share", "jmol", "testjava.sh") result = subprocess.call([testjavapath],stdout=jout) jout.close() if (result == 0): return (True) else: return (False)
def copy_gz_file(gz_source, bz_destination): """ Decompress a gzipped file and install the bzipped verson. This is used by SloaneEncyclopedia.install_from_gz to install several gzipped OEIS database files. INPUT: - ``gz_source`` - string. The name of the gzipped file. - ``bz_destination`` - string. The name of the newly compressed file. """ import gzip from sage.misc.misc import sage_makedirs # Read the gzipped input try: gz_input = gzip.open(gz_source, 'r') db_text = gz_input.read() gz_input.close() except IOError as msg: raise IOError("Error reading gzipped input file:\n%s"%msg) # Write the bzipped output try: sage_makedirs(os.path.dirname(bz_destination)) bz2_output = bz2.BZ2File(bz_destination, 'w') bz2_output.write(db_text) bz2_output.close() except IOError as msg: raise IOError("Error writing bzipped output file:\n%s"%msg)
def path(): from sage.misc.superseded import deprecation deprecation( 17653, 'The sage.misc.db module is deprecated, use the load/save functions from sage.structure.sage_object instead' ) from sage.misc.misc import sage_makedirs sage_makedirs(PATH)
def dump_as_dict(self, filename, keys): from sage.misc.misc import sage_makedirs X = self.as_dict(keys) print "Dumping %s..."%filename s = cPickle.dumps(X,2) dir = "%s/pickles/"%SAGE_DATA sage_makedirs(dir) open("%s/%s"%(dir,filename), "w").write(s)
def __init__(self, f, dir='func_persist'): from sage.misc.misc import sage_makedirs self.__func = f self.__dir = dir sage_makedirs(dir) self.__doc__ = '%s%s%s'%(\ f.__name__, inspect.formatargspec(*inspect.getargs(f.__code__)), f.__doc__)
def __init__(self, f, dir='func_persist'): from sage.misc.misc import sage_makedirs self.__func = f self.__dir = dir sage_makedirs(dir) self.__doc__ = '%s%s%s'%(\ f.func_name, inspect.formatargspec(*inspect.getargs(f.func_code)), f.__doc__)
def citation_dir(app): # Split app.outdir in 3 parts: SAGE_DOC/TYPE/TAIL where TYPE # is a single directory and TAIL can contain multiple directories. # The citation dir is then SAGE_DOC/inventory/TAIL. assert app.outdir.startswith(SAGE_DOC) rel = app.outdir[len(SAGE_DOC):] dirs = rel.split(os.sep) # If SAGE_DOC does not end with a slash, rel will start with # a slash giving an empty dirs[0]. Remove this: if not dirs[0]: dirs.pop(0) dirs = [SAGE_DOC, "inventory"] + dirs[1:] citedir = os.path.join(*dirs) sage_makedirs(citedir) return citedir
def citation_dir(app): # Split app.outdir in 3 parts: SAGE_DOC/TYPE/TAIL where TYPE # is a single directory and TAIL can contain multiple directories. # The citation dir is then SAGE_DOC/inventory/TAIL. assert app.outdir.startswith(SAGE_DOC) rel = app.outdir[len(SAGE_DOC):] dirs = rel.split(os.sep) # If SAGE_DOC does not end with a slash, rel will start with # a slash giving an empty dirs[0]. Remove this: if not dirs[0]: dirs.pop(0) dirs = [SAGE_DOC, "inventory"] + dirs[1:] citedir = os.path.join(*dirs) sage_makedirs(citedir) return citedir
def citation_dir(app: Sphinx) -> Path: outdir = Path(app.outdir).resolve() sage_doc = Path(SAGE_DOC).resolve() if sage_doc in outdir.parents: # Split app.outdir in 3 parts: SAGE_DOC/TYPE/TAIL where TYPE # is a single directory and TAIL can contain multiple directories. # The citation dir is then SAGE_DOC/inventory/TAIL. rel = outdir.relative_to(sage_doc) dirs = list(rel.parts) # If SAGE_DOC does not end with a slash, rel will start with # a slash. Remove this: if dirs[0] == '/': dirs.pop(0) tail = dirs[1:] citedir = (sage_doc / "inventory").joinpath(*tail) else: citedir = outdir / "inventory" sage_makedirs(citedir) return citedir
def _init(self, path): """ Create the database from scratch from the PARI files on John Jones's web page, downloaded (e.g., via wget) to a local directory, which is specified as path above. INPUT: - ``path`` - (default works on William Stein install.) path must be the path to Jones's Number_Fields directory http://hobbes.la.asu.edu/Number_Fields These files should have been downloaded using wget. EXAMPLE: This is how to create the database from scratch, assuming that the number fields are in the default directory above: From a cold start of Sage:: sage: J = JonesDatabase() sage: J._init() # not tested ... This takes about 5 seconds. """ from sage.misc.misc import sage_makedirs n = 0 x = PolynomialRing(RationalField(), "x").gen() self.root = {} self.root[tuple([])] = [x - 1] if not os.path.exists(path): raise IOError("Path %s does not exist." % path) for X in os.listdir(path): if X[-4:] == "solo": Z = path + "/" + X print(X) for Y in os.listdir(Z): if Y[-3:] == ".gp": self._load(Z, Y) sage_makedirs(JONESDATA) save(self.root, JONESDATA + "/jones.sobj")
def save_preview(self): """ Save the preview PNG image See :meth:`preview_filename`. EXAMPLES:: sage: from sage.repl.rich_output.backend_sagenb import SageNbOutputSceneJmol sage: j = SageNbOutputSceneJmol.example() sage: import shutil sage: shutil.rmtree('.jmol_images', ignore_errors=True) sage: j.save_preview() sage: os.listdir('.jmol_images') ['sage1-size32.jmol.png'] """ from sage.misc.misc import sage_makedirs sage_makedirs('.jmol_images') self.preview_png.save_as(self.preview_filename()) world_readable(self.preview_filename())
def __init__(self, f, dir='func_persist', prefix=None, hash=hash, key=None): from sage.misc.misc import sage_makedirs self._func = f self._dir = dir if prefix is None: prefix = f.__name__ self._prefix = dir + "/" + prefix self._hash = hash if key is not None: self.key = key sage_makedirs(dir) self.__doc__ = '%s%s%s'%(\ f.__name__, inspect.formatargspec(*inspect.getargs(f.__code__)), f.__doc__)
def save_preview(self): """ Save the preview PNG image See :meth:`preview_filename`. EXAMPLES:: sage: from sage.repl.rich_output.backend_sagenb import SageNbOutputSceneJmol sage: j = SageNbOutputSceneJmol.example() sage: import shutil sage: shutil.rmtree('.jmol_images', ignore_errors=True) sage: j.save_preview() sage: os.listdir('.jmol_images') ['sage1-size32.jmol.png'] """ from sage.misc.misc import sage_makedirs sage_makedirs('.jmol_images') self.preview_png.save_as(self.preview_filename()) world_readable(self.preview_filename())
def _init(self, path): """ Create the database from scratch from the PARI files on John Jones's web page, downloaded (e.g., via wget) to a local directory, which is specified as path above. INPUT: - ``path`` - (default works on William Stein install.) path must be the path to Jones's Number_Fields directory http://hobbes.la.asu.edu/Number_Fields These files should have been downloaded using wget. EXAMPLES: This is how to create the database from scratch, assuming that the number fields are in the default directory above: From a cold start of Sage:: sage: J = JonesDatabase() sage: J._init() # not tested ... This takes about 5 seconds. """ from sage.misc.misc import sage_makedirs n = 0 x = PolynomialRing(RationalField(), 'x').gen() self.root = {} self.root[tuple([])] = [x - 1] if not os.path.exists(path): raise IOError("Path %s does not exist." % path) for X in os.listdir(path): if X[-4:] == "solo": Z = path + "/" + X print(X) for Y in os.listdir(Z): if Y[-3:] == ".gp": self._load(Z, Y) sage_makedirs(JONESDATA) save(self.root, JONESDATA + "/jones.sobj")
def __init__(self, dir=None, debug=False, viewer=None): from sage.misc.misc import sage_makedirs if dir is None: dir = misc.DOT_SAGE + 'log' self._time = time.strftime('%Y-%m-%d-%H%M%S') dir = os.path.join(os.path.abspath(dir), 'log-' + self._time) sage_makedirs(dir) self._debug = debug self._n = 0 self._dir = dir self._filename = os.path.join(dir, self._filename()) self._output = __IPYTHON__.output_hist self._input = __IPYTHON__.input_hist_raw self._text = '' self._after_output = False self._init() self._input_text = '' self._stopped = False self._viewer = viewer loggers.append(self) print('Now logging to ' + self._filename) self._update() self.view()
def _start(self, alt_message=None, block_during_init=True): from sage.misc.misc import sage_makedirs self.quit() # in case one is already running self._session_number += 1 if self.__logfile is None: # If the 'SAGE_PEXPECT_LOG' environment variable is set and # there is no logfile already defined, then create a # logfile in .sage/pexpect_logs/ if self.__logfilename is None and 'SAGE_PEXPECT_LOG' in os.environ: from sage.env import DOT_SAGE logs = os.path.join(DOT_SAGE, 'pexpect_logs') sage_makedirs(logs) self.__logfilename = '%s/%s-%s-%s-%s.log'%(logs, self.name(), os.getpid(), id(self), self._session_number) if self.__logfilename is not None: self.__logfile = open(self.__logfilename, 'w') cmd = self.__command if self.__verbose_start: print cmd print "Starting %s"%cmd.split()[0] if self.__remote_cleaner and self._server: c = 'sage-native-execute ssh %s "nohup sage -cleaner" &'%self._server os.system(c) # Unset some environment variables for the children to # reduce the chances they do something complicated breaking # the terminal interface. # See Trac #12221 and #13859. pexpect_env = dict(os.environ) pexpect_del_vars = ['TERM', 'COLUMNS'] for i in pexpect_del_vars: try: del pexpect_env[i] except KeyError: pass # Run child from self.__path currentdir = os.getcwd() os.chdir(self.__path) try: try: self._expect = SageSpawn(cmd, logfile=self.__logfile, timeout=None, # no timeout env=pexpect_env, name=self._repr_(), quit_string=self._quit_string()) except (ExceptionPexpect, pexpect.EOF) as e: # Change pexpect errors to RuntimeError raise RuntimeError("unable to start %s because the command %r failed: %s\n%s" % (self.name(), cmd, e, self._install_hints())) except BaseException: self._expect = None self._session_number = BAD_SESSION raise finally: os.chdir(currentdir) if self._do_cleaner(): cleaner.cleaner(self._expect.pid, cmd) self._expect.maxread = self.__maxread self._expect.delaybeforesend = 0 try: self._expect.expect(self._prompt) except (pexpect.TIMEOUT, pexpect.EOF): self._expect = None self._session_number = BAD_SESSION raise RuntimeError("unable to start %s" % self.name()) self._expect.timeout = None # Calling tcsetattr earlier exposes bugs in various pty # implementations, see :trac:`16474`. Since we haven't # **written** anything so far it is safe to wait with # switching echo off until now. if not self._terminal_echo: self._expect.setecho(0) with gc_disabled(): if block_during_init: for X in self.__init_code: self.eval(X) else: for X in self.__init_code: self._send(X)
import os from sage.all import save from sage.env import SAGE_SHARE from sage.misc.misc import sage_makedirs install_root = os.path.join(SAGE_SHARE, 'odlyzko') target = os.path.join(install_root, 'zeros.sobj') if __name__ == '__main__': sage_makedirs(install_root) print("Creating Odlyzko database.") F = [float(x) for x in open("src/zeros6").readlines()] save(F, target)
def _start(self, alt_message=None, block_during_init=True): from sage.misc.misc import sage_makedirs self.quit() # in case one is already running global failed_to_start self._session_number += 1 current_path = os.path.abspath('.') dir = self.__path sage_makedirs(dir) os.chdir(dir) #If the 'SAGE_PEXPECT_LOG' environment variable is set and #the current logfile is None, then set the logfile to be one #in .sage/pexpect_logs/ if self.__logfile is None and 'SAGE_PEXPECT_LOG' in os.environ: from sage.misc.all import DOT_SAGE logs = '%s/pexpect_logs'%DOT_SAGE sage_makedirs(logs) filename = '%s/%s-%s-%s-%s.log'%(logs, self.name(), os.getpid(), id(self), self._session_number) self.__logfile = open(filename, 'w') cmd = self.__command if self.__verbose_start: print cmd print "Starting %s"%cmd.split()[0] try: if self.__remote_cleaner and self._server: c = 'sage-native-execute ssh %s "nohup sage -cleaner" &'%self._server os.system(c) # Unset $TERM for the children to reduce the chances they do # something complicated breaking the terminal interface. # See Trac #12221. pexpect_env = dict(os.environ) try: del pexpect_env["TERM"] except KeyError: pass self._expect = pexpect.spawn(cmd, logfile=self.__logfile, env=pexpect_env) if self._do_cleaner(): cleaner.cleaner(self._expect.pid, cmd) except (ExceptionPexpect, pexpect.EOF, IndexError): self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%( self.name(), cmd, self._install_hints()) os.chdir(current_path) self._expect.timeout = self.__max_startup_time #self._expect.setmaxread(self.__maxread) self._expect.maxread = self.__maxread self._expect.delaybeforesend = 0 try: self._expect.expect(self._prompt) except (pexpect.TIMEOUT, pexpect.EOF), msg: self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError, "Unable to start %s"%self.name()
def cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are created in a temporary directory. INPUT: - ``filename`` -- the name of the file to be compiled. Should end with 'pyx'. - ``verbose`` (integer, default 0) -- level of verbosity. A negative value ensures complete silence. - ``compile_message`` (bool, default False) -- if True, print ``'Compiling <filename>...'`` to the standard error. - ``use_cache`` (bool, default False) -- if True, check the temporary build directory to see if there is already a corresponding .so file. If so, and if the .so file is newer than the Cython file, don't recompile, just reuse the .so file. - ``create_local_c_file`` (bool, default False) -- if True, save a copy of the ``.c`` or ``.cpp`` file in the current directory. - ``annotate`` (bool, default True) -- if True, create an html file which annotates the conversion from .pyx to .c. By default this is only created in the temporary directory, but if ``create_local_c_file`` is also True, then save a copy of the .html file in the current directory. - ``sage_namespace`` (bool, default True) -- if True, import ``sage.all``. - ``create_local_so_file`` (bool, default False) -- if True, save a copy of the compiled .so file in the current directory. OUTPUT: a tuple ``(name, dir)`` where ``name`` is the name of the compiled module and ``dir`` is the directory containing the generated files. TESTS: Before :trac:`12975`, it would have been needed to write ``#clang c++``, but upper case ``C++`` has resulted in an error. Using pkgconfig to find the libraries, headers and macros. This is a work around while waiting for :trac:`22461` which will offer a better solution:: sage: code = [ ....: "#clang C++", ....: "from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular", ....: "from sage.libs.singular.polynomial cimport singular_polynomial_pow", ....: "def test(MPolynomial_libsingular p):", ....: " singular_polynomial_pow(&p._poly, p._poly, 2, p._parent_ring)"] sage: cython(os.linesep.join(code)) The function ``test`` now manipulates internal C data of polynomials, squaring them:: sage: P.<x,y>=QQ[] sage: test(x) sage: x x^2 Check that compiling C++ code works:: sage: cython("# distutils: language = c++\n"+ ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") Check that compiling C++ code works when creating a local C file, first moving to a tempdir to avoid clutter. Before :trac:`22113`, the create_local_c_file argument was not tested for C++ code:: sage: d = sage.misc.temporary_file.tmp_dir() sage: os.chdir(d) sage: with open("test.pyx", 'w') as f: ....: _ = f.write("# distutils: language = c++\n" ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") sage: output = sage.misc.cython.cython("test.pyx", create_local_c_file=True) Accessing a ``.pxd`` file from the current directory works:: sage: d = sage.misc.temporary_file.tmp_dir() sage: os.chdir(d) sage: with open("helper.pxd", 'w') as f: ....: _ = f.write("cdef inline int the_answer(): return 42") sage: cython(''' ....: from helper cimport the_answer ....: print(the_answer()) ....: ''') 42 Warning and error messages generated by Cython are properly handled. Warnings are only shown if verbose >= 0:: sage: code = ''' ....: def test_unreachable(): ....: raise Exception ....: return 42 ....: ''' sage: cython(code, verbose=-1) sage: cython(code, verbose=0) warning: ...:4:4: Unreachable code sage: cython("foo = bar\n") Traceback (most recent call last): ... RuntimeError: Error compiling Cython file: ------------------------------------------------------------ ... foo = bar ^ ------------------------------------------------------------ <BLANKLINE> ...:1:6: undeclared name not builtin: bar sage: cython("cdef extern from 'no_such_header_file': pass") Traceback (most recent call last): ... RuntimeError: ... As of :trac:`29139` the default is ``cdivision=True``:: sage: cython(''' ....: cdef size_t foo = 3/2 ....: ''') """ if not filename.endswith('pyx'): print("Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr) # base is the name of the .so module that we create. If we are # creating a local shared object file, we use a more natural # naming convention. If we are not creating a local shared object # file, the main constraint is that it is unique and determined by # the file that we're running Cython on, so that in some cases we # can cache the result (e.g., recompiling the same pyx file during # the same session). if create_local_so_file: base, ext = os.path.splitext(os.path.basename(filename)) else: base = os.path.abspath(filename) base = sanitize(base) # This is the *temporary* directory where we store the pyx file. # This is deleted when Sage exits, which means pyx files must be # rebuilt every time Sage is restarted at present. target_dir = os.path.join(SPYX_TMP, base) # Build directory for Cython/distutils build_dir = os.path.join(target_dir, "build") if os.path.exists(target_dir): # There is already a module here. Maybe we do not have to rebuild? # Find the name. if use_cache: from sage.misc.sageinspect import loadable_module_extension prev_so = [F for F in os.listdir(target_dir) if F.endswith(loadable_module_extension())] if len(prev_so) > 0: prev_so = prev_so[0] # should have length 1 because of deletes below if os.path.getmtime(filename) <= os.path.getmtime('%s/%s' % (target_dir, prev_so)): # We do not have to rebuild. return prev_so[:-len(loadable_module_extension())], target_dir # Delete all ordinary files in target_dir for F in os.listdir(target_dir): G = os.path.join(target_dir, F) if os.path.isdir(G): continue try: os.unlink(G) except OSError: pass else: sage_makedirs(target_dir) if create_local_so_file: name = base else: global sequence_number if base not in sequence_number: sequence_number[base] = 0 name = '%s_%s' % (base, sequence_number[base]) # increment the sequence number so will use a different one next time. sequence_number[base] += 1 if compile_message: sys.stderr.write("Compiling {}...\n".format(filename)) sys.stderr.flush() # Copy original file to the target directory. pyxfile = os.path.join(target_dir, name + ".pyx") shutil.copy(filename, pyxfile) # Add current working directory to includes. This is needed because # we cythonize from a different directory. See Trac #24764. standard_libs, standard_libdirs, standard_includes, aliases = _standard_libs_libdirs_incdirs_aliases() includes = [os.getcwd()] + standard_includes # Now do the actual build, directly calling Cython and distutils from Cython.Build import cythonize from Cython.Compiler.Errors import CompileError import Cython.Compiler.Options try: # Import setuptools before importing distutils, so that setuptools # can replace distutils by its own vendored copy. import setuptools from setuptools.dist import Distribution from setuptools.extension import Extension except ImportError: # Fall back to distutils (stdlib); note that it is deprecated # in Python 3.10, 3.11; https://www.python.org/dev/peps/pep-0632/ from distutils.dist import Distribution from distutils.core import Extension from distutils.log import set_verbosity set_verbosity(verbose) Cython.Compiler.Options.annotate = annotate Cython.Compiler.Options.embed_pos_in_docstring = True Cython.Compiler.Options.pre_import = "sage.all" if sage_namespace else None extra_compile_args = ['-w'] # no warnings extra_link_args = [] if sys.platform == 'cygwin': # Link using --enable-auto-image-base, reducing the likelihood of the # new DLL colliding with existing DLLs in memory. # Note: Cygwin locates --enable-auto-image-base DLLs in the range # 0x4:00000000 up to 0x6:00000000; this is documented in heap.cc in the # Cygwin sources, while 0x6:00000000 and up is reserved for the Cygwin # heap. # In practice, Sage has enough DLLs that when rebasing everything we # use up through, approximately, 0x4:80000000 though there is nothing # precise here. When running 'rebase' it just start from 0x2:00000000 # (below that is reserved for Cygwin's DLL and some internal # structures). # Therefore, to minimize the likelihood of collision with one of Sage's # standard DLLs, while giving ~2GB (should be more than enough) for # Sage to grow, we base these DLLs from 0x5:8000000, leaving again ~2GB # for temp DLLs which in normal use should be more than enough. # See https://trac.sagemath.org/ticket/28258 # It should be noted, this is not a bulletproof solution; there is # still a potential for DLL overlaps with this. But this reduces the # probability thereof, especially in normal practice. dll_filename = os.path.splitext(pyxfile)[0] + '.dll' image_base = _compute_dll_image_base(dll_filename) extra_link_args.extend(['-Wl,--disable-auto-image-base', '-Wl,--image-base=0x{:x}'.format(image_base)]) ext = Extension(name, sources=[pyxfile], extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, libraries=standard_libs, library_dirs=standard_libdirs) directives = dict(language_level=sys.version_info[0], cdivision=True) try: # Change directories to target_dir so that Cython produces the correct # relative path; https://trac.sagemath.org/ticket/24097 with restore_cwd(target_dir): try: ext, = cythonize([ext], aliases=aliases, include_path=includes, compiler_directives=directives, quiet=(verbose <= 0), errors_to_stderr=False, use_listing_file=True) finally: # Read the "listing file" which is the file containing # warning and error messages generated by Cython. try: with open(name + ".lis") as f: cython_messages = f.read() except IOError: cython_messages = "Error compiling Cython file" except CompileError: raise RuntimeError(cython_messages.strip()) if verbose >= 0: sys.stderr.write(cython_messages) sys.stderr.flush() if create_local_c_file: shutil.copy(os.path.join(target_dir, ext.sources[0]), os.curdir) if annotate: shutil.copy(os.path.join(target_dir, name + ".html"), os.curdir) # This emulates running "setup.py build" with the correct options dist = Distribution() dist.ext_modules = [ext] dist.include_dirs = includes buildcmd = dist.get_command_obj("build") buildcmd.build_base = build_dir buildcmd.build_lib = target_dir try: # Capture errors from distutils and its child processes with open(os.path.join(target_dir, name + ".err"), 'w+') as errfile: try: # Redirect stderr to errfile. We use the file descriptor # number "2" instead of "sys.stderr" because we really # want to redirect the messages from GCC. These are sent # to the actual stderr, regardless of what sys.stderr is. sys.stderr.flush() with redirection(2, errfile, close=False): dist.run_command("build") finally: errfile.seek(0) distutils_messages = errfile.read() except Exception as msg: msg = str(msg) + "\n" + distutils_messages raise RuntimeError(msg.strip()) if verbose >= 0: sys.stderr.write(distutils_messages) sys.stderr.flush() if create_local_so_file: # Copy module to current directory from sage.misc.sageinspect import loadable_module_extension shutil.copy(os.path.join(target_dir, name + loadable_module_extension()), os.curdir) return name, target_dir
import os from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField from sage.rings.arith import GCD import sage.misc.db as db from sage.misc.misc import SAGE_ROOT, sage_makedirs # TODO: # I messed up and now self.d is i and self.i is d, # i.e., the degree and number are swapped. PATH = SAGE_ROOT + "/src/tables/modular/gamma0/db/" sage_makedirs(PATH) class ModularForm: def __init__(self, N, d, i, Wq, r, charpolys, disc): self.N = N self.d = d self.i = i self.Wq = Wq self.r = r self.charpolys = charpolys self.disc = disc def __repr__(self): s = "Modular form: level %s, degree %s, number %s"%( self.N,self.d,self.i) + \ ", Wq: %s, an rank bnd: %s"%( self.Wq, self.r)
def export_image(self, targetfile, datafile, #name (path) of data file Jmol can read or script file telling it what to read or load datafile_cmd='script', #"script" or "load" image_type ='PNG', #PNG, JPG, GIF figsize=5, **kwds): r""" This executes JmolData.jar to make an image file. INPUT: - targetfile -- the full path to the file where the image should be written. - datafile -- full path to the data file Jmol can read or text of a script telling Jmol what to read or load. - datafile_cmd -- (default ``'script'``) ``'load'`` or ``'script'`` should be ``"load"`` for a data file. - image_type -- (default ``"PNG"``) ``'PNG'`` ``'JPG'`` or ``'GIF'`` - figsize -- number (default 5) equal to (pixels/side)/100 OUTPUT: Image file, .png, .gif or .jpg (default .png) .. note:: Examples will generate an error message if a functional Java Virtual Machine (JVM) is not installed on the machine the Sage instance is running on. .. warning:: Programmers using this module should check that the JVM is available before making calls to avoid the user getting error messages. Check for the JVM using the function :meth:`is_jvm_available`, which returns True if a JVM is available. EXAMPLES: Use Jmol to load a pdb file containing some DNA from a web data base and make an image of the DNA. If you execute this in the notebook, the image will appear in the output cell:: sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() sage: script = "load =1lcd;display DNA;moveto 0.0 { -473 -713 -518 59.94} 100.0 0.0 0.0 {21.17 26.72 27.295} 27.544636 {0.0 0.0 0.0} -25.287832 64.8414 0.0;" sage: testfile = tmp_filename(ext="DNA.png") sage: JData.export_image(targetfile=testfile,datafile=script,image_type="PNG") # optional -- internet sage: print os.path.exists(testfile) # optional -- internet True Use Jmol to save an image of a 3-D object created in Sage. This method is used internally by plot3d to generate static images. This example doesn't have correct scaling:: sage: from sage.interfaces.jmoldata import JmolData sage: JData = JmolData() sage: D=dodecahedron() sage: from sage.misc.misc import SAGE_TMP sage: archive_name=os.path.join(SAGE_TMP, "archive.jmol.zip") sage: D.export_jmol(archive_name) #not scaled properly...need some more steps. sage: testfile = os.path.join(SAGE_TMP, "testimage.png") sage: script = 'set defaultdirectory "%s"\n script SCRIPT\n'%archive_name sage: JData.export_image(targetfile =testfile,datafile = script, image_type="PNG") # optional -- java sage: print os.path.exists(testfile) # optional -- java True """ if (self.is_jvm_available()): # Set up paths, file names and scripts jmolpath = os.path.join(SAGE_LOCAL, "share", "jmol", "JmolData.jar") launchscript = "" if (datafile_cmd!='script'): launchscript = "load " launchscript = launchscript + datafile #print launchscript imagescript = "write "+ image_type +" "+targetfile+"\n" #print imagescript sizeStr = "%sx%s" %(figsize*100,figsize*100) #scratch file for Jmol errors and status jmolscratch = os.path.join(DOT_SAGE, "sage_notebook.sagenb", "jmol_scratch") if not os.path.exists(jmolscratch): sage_makedirs(jmolscratch) scratchout = os.path.join(jmolscratch,"jmolout.txt") jout=open(scratchout,'w') #now call the java application and write the file. result = subprocess.call(["java","-Xmx512m","-Djava.awt.headless=true","-jar",jmolpath,"-iox","-g",sizeStr,"-J",launchscript,"-j",imagescript],stdout=jout) jout.close() else: errStr = "Java Virtual Machine not available.\n" errStr +="This should be checked before calling JmolData().export_image().\n" errStr +="Use JmolData().is_jvm_available() to check.\n" errStr +="Administrator should install JVM." raise JmolDataError(errStr)
def cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are created in a temporary directory. INPUT: - ``filename`` -- the name of the file to be compiled. Should end with 'pyx'. - ``verbose`` (integer, default 0) -- level of verbosity. - ``compile_message`` (bool, default False) -- if True, print ``'Compiling <filename>...'`` to the standard error. - ``use_cache`` (bool, default False) -- if True, check the temporary build directory to see if there is already a corresponding .so file. If so, and if the .so file is newer than the Cython file, don't recompile, just reuse the .so file. - ``create_local_c_file`` (bool, default False) -- if True, save a copy of the ``.c`` or ``.cpp`` file in the current directory. - ``annotate`` (bool, default True) -- if True, create an html file which annotates the conversion from .pyx to .c. By default this is only created in the temporary directory, but if ``create_local_c_file`` is also True, then save a copy of the .html file in the current directory. - ``sage_namespace`` (bool, default True) -- if True, import ``sage.all``. - ``create_local_so_file`` (bool, default False) -- if True, save a copy of the compiled .so file in the current directory. TESTS: Before :trac:`12975`, it would have been needed to write ``#clang c++``, but upper case ``C++`` has resulted in an error. Using pkgconfig to find the libraries, headers and macros. This is a work around while waiting for :trac:`22461` which will offer a better solution:: sage: code = [ ....: "#clang C++", ....: "from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular", ....: "from sage.libs.singular.polynomial cimport singular_polynomial_pow", ....: "def test(MPolynomial_libsingular p):", ....: " singular_polynomial_pow(&p._poly, p._poly, 2, p._parent_ring)"] sage: cython(os.linesep.join(code)) The function ``test`` now manipulates internal C data of polynomials, squaring them:: sage: P.<x,y>=QQ[] sage: test(x) sage: x x^2 Check that compiling C++ code works:: sage: cython("# distutils: language = c++\n"+ ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") Check that compiling C++ code works when creating a local C file, first moving to a tempdir to avoid clutter. Before :trac:`22113`, the create_local_c_file argument was not tested for C++ code:: sage: import sage.misc.cython sage: d = sage.misc.temporary_file.tmp_dir() sage: os.chdir(d) sage: with open("test.pyx", 'w') as f: ....: _ = f.write("# distutils: language = c++\n" ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") sage: output = sage.misc.cython.cython("test.pyx", create_local_c_file=True) Sage used to automatically include various ``.pxi`` files. Since :trac:`22805`, we no longer do this. But we make sure to give a useful message in case the ``.pxi`` files were needed:: sage: cython("sig_malloc(0)") Traceback (most recent call last): ... RuntimeError: Error converting ... to C NOTE: Sage no longer automatically includes the deprecated files "cdefs.pxi", "signals.pxi" and "stdsage.pxi" in Cython files. You can fix your code by adding "from cysignals.memory cimport sig_malloc". """ if not filename.endswith('pyx'): print( "Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr) # base is the name of the .so module that we create. If we are # creating a local shared object file, we use a more natural # naming convention. If we are not creating a local shared object # file, the main constraint is that it is unique and determined by # the file that we're running Cython on, so that in some cases we # can cache the result (e.g., recompiling the same pyx file during # the same session). if create_local_so_file: base, ext = os.path.splitext(os.path.basename(filename)) base = sanitize(base) else: base = sanitize(os.path.abspath(filename)) # This is the *temporary* directory where we store the pyx file. # This is deleted when Sage exits, which means pyx files must be # rebuilt every time Sage is restarted at present. target_dir = os.path.join(SPYX_TMP, base) # Build directory for Cython/distutils build_dir = os.path.join(target_dir, "build") if os.path.exists(target_dir): # There is already a module here. Maybe we do not have to rebuild? # Find the name. if use_cache: from sage.misc.sageinspect import loadable_module_extension prev_so = [ F for F in os.listdir(target_dir) if F.endswith(loadable_module_extension()) ] if len(prev_so) > 0: prev_so = prev_so[ 0] # should have length 1 because of deletes below if os.path.getmtime(filename) <= os.path.getmtime( '%s/%s' % (target_dir, prev_so)): # We do not have to rebuild. return prev_so[:-len(loadable_module_extension() )], target_dir # Delete all ordinary files in target_dir for F in os.listdir(target_dir): G = os.path.join(target_dir, F) if os.path.isdir(G): continue try: os.unlink(G) except OSError: pass else: sage_makedirs(target_dir) if create_local_so_file: name = base else: global sequence_number if base not in sequence_number: sequence_number[base] = 0 name = '%s_%s' % (base, sequence_number[base]) # increment the sequence number so will use a different one next time. sequence_number[base] += 1 if compile_message: print("Compiling {}...".format(filename), file=sys.stderr) with open(filename) as f: (preparsed, libs, includes, language, additional_source_files, extra_args, libdirs) = _pyx_preparse(f.read()) # New filename with preparsed code. # NOTE: if we ever stop preparsing, we should still copy the # original file to the target directory. pyxfile = os.path.join(target_dir, name + ".pyx") with open(pyxfile, 'w') as f: f.write(preparsed) extra_sources = [] for fname in additional_source_files: fname = fname.replace("$SAGE_SRC", SAGE_SRC) fname = fname.replace("$SAGE_LOCAL", SAGE_LOCAL) extra_sources.append(fname) # Now do the actual build, directly calling Cython and distutils from Cython.Build import cythonize from Cython.Compiler.Errors import CompileError import Cython.Compiler.Options from distutils.dist import Distribution from distutils.core import Extension from distutils.log import set_verbosity set_verbosity(verbose) Cython.Compiler.Options.annotate = annotate Cython.Compiler.Options.embed_pos_in_docstring = True Cython.Compiler.Options.pre_import = "sage.all" if sage_namespace else None ext = Extension(name, sources=[pyxfile] + extra_sources, libraries=libs, library_dirs=[os.path.join(SAGE_LOCAL, "lib")] + libdirs, extra_compile_args=extra_args, language=language) orig_cwd = os.getcwd() try: # Change directories to target_dir so that Cython produces the correct # relative path; https://trac.sagemath.org/ticket/24097 os.chdir(target_dir) ext, = cythonize([ext], aliases=cython_aliases(), include_path=includes, quiet=not verbose) except CompileError: # Check for names in old_pxi_names note = '' for pxd, names in old_pxi_names.items(): for name in names: if re.search(r"\b{}\b".format(name), preparsed): note += dedent(""" NOTE: Sage no longer automatically includes the deprecated files "cdefs.pxi", "signals.pxi" and "stdsage.pxi" in Cython files. You can fix your code by adding "from {} cimport {}". """.format(pxd, name)) raise RuntimeError("Error converting {} to C".format(filename) + note) finally: os.chdir(orig_cwd) if create_local_c_file: shutil.copy(os.path.join(target_dir, ext.sources[0]), os.curdir) if annotate: shutil.copy(os.path.join(target_dir, name + ".html"), os.curdir) # This emulates running "setup.py build" with the correct options dist = Distribution() dist.ext_modules = [ext] dist.include_dirs = includes buildcmd = dist.get_command_obj("build") buildcmd.build_base = build_dir buildcmd.build_lib = target_dir dist.run_command("build") if create_local_so_file: # Copy module to current directory from sage.misc.sageinspect import loadable_module_extension shutil.copy( os.path.join(target_dir, name + loadable_module_extension()), os.curdir) return name, target_dir
def path(): from sage.misc.misc import sage_makedirs sage_makedirs(PATH)
def _start(self, alt_message=None, block_during_init=True): from sage.misc.misc import sage_makedirs self.quit() # in case one is already running global failed_to_start self._session_number += 1 current_path = os.path.abspath('.') dir = self.__path sage_makedirs(dir) os.chdir(dir) #If the 'SAGE_PEXPECT_LOG' environment variable is set and #the current logfile is None, then set the logfile to be one #in .sage/pexpect_logs/ if self.__logfile is None and 'SAGE_PEXPECT_LOG' in os.environ: from sage.env import DOT_SAGE logs = '%s/pexpect_logs'%DOT_SAGE sage_makedirs(logs) filename = '%s/%s-%s-%s-%s.log'%(logs, self.name(), os.getpid(), id(self), self._session_number) self.__logfile = open(filename, 'w') cmd = self.__command if self.__verbose_start: print cmd print "Starting %s"%cmd.split()[0] try: if self.__remote_cleaner and self._server: c = 'sage-native-execute ssh %s "nohup sage -cleaner" &'%self._server os.system(c) # Unset some environment variables for the children to # reduce the chances they do something complicated breaking # the terminal interface. # See Trac #12221 and #13859. pexpect_env = dict(os.environ) pexpect_del_vars = ['TERM', 'COLUMNS'] for i in pexpect_del_vars: try: del pexpect_env[i] except KeyError: pass self._expect = pexpect.spawn(cmd, logfile=self.__logfile, env=pexpect_env) if self._do_cleaner(): cleaner.cleaner(self._expect.pid, cmd) except (ExceptionPexpect, pexpect.EOF, IndexError): self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%( self.name(), cmd, self._install_hints()) os.chdir(current_path) self._expect.timeout = self.__max_startup_time #self._expect.setmaxread(self.__maxread) self._expect.maxread = self.__maxread self._expect.delaybeforesend = 0 try: self._expect.expect(self._prompt) except (pexpect.TIMEOUT, pexpect.EOF), msg: self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError, "Unable to start %s"%self.name()
def path(): from sage.misc.superseded import deprecation deprecation(17653, 'The sage.misc.db module is deprecated, use the load/save functions from sage.structure.sage_object instead') from sage.misc.misc import sage_makedirs sage_makedirs(PATH)
- ``bz_destination`` - string. The name of the newly compressed file. """ import gzip from sage.misc.misc import sage_makedirs # Read the gzipped input try: gz_input = gzip.open(gz_source, 'r') db_text = gz_input.read() gz_input.close() except IOError, msg: raise IOError, "Error reading gzipped input file:\n%s"%msg # Write the bzipped output try: sage_makedirs(os.path.dirname(bz_destination)) bz2_output = bz2.BZ2File(bz_destination, 'w') bz2_output.write(db_text) bz2_output.close() except IOError, msg: raise IOError, "Error writing bzipped output file:\n%s"%msg def parse_sequence(text): entry = re.compile(r'%(?P<letter>[A-Za-z]) A(?P<num>\d{6}) (?P<body>.*)$') unsigned, signed, list = [], [], [] description = '' seqnum = -1 # Fix broken lines: the next line is indented. text = text.replace('\n ', '');
def _start(self, alt_message=None, block_during_init=True): from sage.misc.misc import sage_makedirs self.quit() # in case one is already running global failed_to_start self._session_number += 1 #If the 'SAGE_PEXPECT_LOG' environment variable is set and #the current logfile is None, then set the logfile to be one #in .sage/pexpect_logs/ if self.__logfile is None and 'SAGE_PEXPECT_LOG' in os.environ: from sage.env import DOT_SAGE logs = os.path.join(DOT_SAGE, 'pexpect_logs') sage_makedirs(logs) filename = '%s/%s-%s-%s-%s.log'%(logs, self.name(), os.getpid(), id(self), self._session_number) self.__logfile = open(filename, 'w') cmd = self.__command if self.__verbose_start: print cmd print "Starting %s"%cmd.split()[0] try: if self.__remote_cleaner and self._server: c = 'sage-native-execute ssh %s "nohup sage -cleaner" &'%self._server os.system(c) # Unset some environment variables for the children to # reduce the chances they do something complicated breaking # the terminal interface. # See Trac #12221 and #13859. pexpect_env = dict(os.environ) pexpect_del_vars = ['TERM', 'COLUMNS'] for i in pexpect_del_vars: try: del pexpect_env[i] except KeyError: pass # Run child from self.__path currentdir = os.getcwd() os.chdir(self.__path) self._expect = pexpect.spawn(cmd, logfile=self.__logfile, env=pexpect_env) os.chdir(currentdir) if self._do_cleaner(): cleaner.cleaner(self._expect.pid, cmd) except (ExceptionPexpect, pexpect.EOF, IndexError): self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError("unable to start %s because the command %r failed\n%s" % ( self.name(), cmd, self._install_hints())) self._expect.timeout = self.__max_startup_time self._expect.maxread = self.__maxread self._expect.delaybeforesend = 0 try: self._expect.expect(self._prompt) except (pexpect.TIMEOUT, pexpect.EOF) as msg: self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError("unable to start %s" % self.name()) self._expect.timeout = None # Calling tcsetattr earlier exposes bugs in various pty # implementations, see :trac:`16474`. Since we haven't # **written** anything so far it is safe to wait with # switching echo off until now. if not self._terminal_echo: self._expect.setecho(0) with gc_disabled(): if block_during_init: for X in self.__init_code: self.eval(X) else: for X in self.__init_code: self._send(X)
def _start(self, alt_message=None, block_during_init=True): from sage.misc.misc import sage_makedirs self.quit() # in case one is already running global failed_to_start self._session_number += 1 current_path = os.path.abspath('.') dir = self.__path sage_makedirs(dir) os.chdir(dir) #If the 'SAGE_PEXPECT_LOG' environment variable is set and #the current logfile is None, then set the logfile to be one #in .sage/pexpect_logs/ if self.__logfile is None and 'SAGE_PEXPECT_LOG' in os.environ: from sage.env import DOT_SAGE logs = '%s/pexpect_logs'%DOT_SAGE sage_makedirs(logs) filename = '%s/%s-%s-%s-%s.log'%(logs, self.name(), os.getpid(), id(self), self._session_number) self.__logfile = open(filename, 'w') cmd = self.__command if self.__verbose_start: print cmd print "Starting %s"%cmd.split()[0] try: if self.__remote_cleaner and self._server: c = 'sage-native-execute ssh %s "nohup sage -cleaner" &'%self._server os.system(c) # Unset some environment variables for the children to # reduce the chances they do something complicated breaking # the terminal interface. # See Trac #12221 and #13859. pexpect_env = dict(os.environ) pexpect_del_vars = ['TERM', 'COLUMNS'] for i in pexpect_del_vars: try: del pexpect_env[i] except KeyError: pass self._expect = pexpect.spawn(cmd, logfile=self.__logfile, env=pexpect_env) if self._do_cleaner(): cleaner.cleaner(self._expect.pid, cmd) except (ExceptionPexpect, pexpect.EOF, IndexError): self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError("Unable to start %s because the command '%s' failed.\n%s"%( self.name(), cmd, self._install_hints())) os.chdir(current_path) self._expect.timeout = self.__max_startup_time #self._expect.setmaxread(self.__maxread) self._expect.maxread = self.__maxread self._expect.delaybeforesend = 0 try: self._expect.expect(self._prompt) except (pexpect.TIMEOUT, pexpect.EOF) as msg: self._expect = None self._session_number = BAD_SESSION failed_to_start.append(self.name()) raise RuntimeError("Unable to start %s"%self.name()) self._expect.timeout = None # Calling tcsetattr earlier exposes bugs in various pty # implementations, see :trac:`16474`. Since we haven't # **written** anything so far it is safe to wait with # switching echo off until now. if not self._terminal_echo: self._expect.setecho(0) with gc_disabled(): if block_during_init: for X in self.__init_code: self.eval(X) else: for X in self.__init_code: self._send(X)
def cython(filename, verbose=0, compile_message=False, use_cache=False, create_local_c_file=False, annotate=True, sage_namespace=True, create_local_so_file=False): r""" Compile a Cython file. This converts a Cython file to a C (or C++ file), and then compiles that. The .c file and the .so file are created in a temporary directory. INPUT: - ``filename`` -- the name of the file to be compiled. Should end with 'pyx'. - ``verbose`` (integer, default 0) -- level of verbosity. A negative value ensures complete silence. - ``compile_message`` (bool, default False) -- if True, print ``'Compiling <filename>...'`` to the standard error. - ``use_cache`` (bool, default False) -- if True, check the temporary build directory to see if there is already a corresponding .so file. If so, and if the .so file is newer than the Cython file, don't recompile, just reuse the .so file. - ``create_local_c_file`` (bool, default False) -- if True, save a copy of the ``.c`` or ``.cpp`` file in the current directory. - ``annotate`` (bool, default True) -- if True, create an html file which annotates the conversion from .pyx to .c. By default this is only created in the temporary directory, but if ``create_local_c_file`` is also True, then save a copy of the .html file in the current directory. - ``sage_namespace`` (bool, default True) -- if True, import ``sage.all``. - ``create_local_so_file`` (bool, default False) -- if True, save a copy of the compiled .so file in the current directory. OUTPUT: a tuple ``(name, dir)`` where ``name`` is the name of the compiled module and ``dir`` is the directory containing the generated files. TESTS: Before :trac:`12975`, it would have been needed to write ``#clang c++``, but upper case ``C++`` has resulted in an error. Using pkgconfig to find the libraries, headers and macros. This is a work around while waiting for :trac:`22461` which will offer a better solution:: sage: code = [ ....: "#clang C++", ....: "from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular", ....: "from sage.libs.singular.polynomial cimport singular_polynomial_pow", ....: "def test(MPolynomial_libsingular p):", ....: " singular_polynomial_pow(&p._poly, p._poly, 2, p._parent_ring)"] sage: cython(os.linesep.join(code)) The function ``test`` now manipulates internal C data of polynomials, squaring them:: sage: P.<x,y>=QQ[] sage: test(x) sage: x x^2 Check that compiling C++ code works:: sage: cython("# distutils: language = c++\n"+ ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") Check that compiling C++ code works when creating a local C file, first moving to a tempdir to avoid clutter. Before :trac:`22113`, the create_local_c_file argument was not tested for C++ code:: sage: import sage.misc.cython sage: d = sage.misc.temporary_file.tmp_dir() sage: os.chdir(d) sage: with open("test.pyx", 'w') as f: ....: _ = f.write("# distutils: language = c++\n" ....: "from libcpp.vector cimport vector\n" ....: "cdef vector[int] * v = new vector[int](4)\n") sage: output = sage.misc.cython.cython("test.pyx", create_local_c_file=True) Accessing a ``.pxd`` file from the current directory works:: sage: import sage.misc.cython sage: d = sage.misc.temporary_file.tmp_dir() sage: os.chdir(d) sage: with open("helper.pxd", 'w') as f: ....: f.write("cdef inline int the_answer(): return 42") sage: cython(''' ....: from helper cimport the_answer ....: print(the_answer()) ....: ''') 42 Warning and error messages generated by Cython are properly handled. Warnings are only shown if verbose >= 0:: sage: code = ''' ....: def test_unreachable(): ....: raise Exception ....: return 42 ....: ''' sage: cython(code, verbose=-1) sage: cython(code, verbose=0) warning: ...:4:4: Unreachable code sage: cython("foo = bar\n") Traceback (most recent call last): ... RuntimeError: Error compiling Cython file: ------------------------------------------------------------ ... foo = bar ^ ------------------------------------------------------------ <BLANKLINE> ...:1:6: undeclared name not builtin: bar sage: cython("cdef extern from 'no_such_header_file': pass") Traceback (most recent call last): ... RuntimeError: ... Sage used to automatically include various ``.pxi`` files. Since :trac:`22805`, we no longer do this. But we make sure to give a useful message in case the ``.pxi`` files were needed:: sage: cython("sig_malloc(0)\n") Traceback (most recent call last): ... RuntimeError: Error compiling Cython file: ------------------------------------------------------------ ... sig_malloc(0) ^ ------------------------------------------------------------ <BLANKLINE> ...:1:0: undeclared name not builtin: sig_malloc <BLANKLINE> NOTE: Sage no longer automatically includes the deprecated files "cdefs.pxi", "signals.pxi" and "stdsage.pxi" in Cython files. You can fix your code by adding "from cysignals.memory cimport sig_malloc". """ if not filename.endswith('pyx'): print("Warning: file (={}) should have extension .pyx".format(filename), file=sys.stderr) # base is the name of the .so module that we create. If we are # creating a local shared object file, we use a more natural # naming convention. If we are not creating a local shared object # file, the main constraint is that it is unique and determined by # the file that we're running Cython on, so that in some cases we # can cache the result (e.g., recompiling the same pyx file during # the same session). if create_local_so_file: base, ext = os.path.splitext(os.path.basename(filename)) else: base = os.path.abspath(filename) base = sanitize(base) # This is the *temporary* directory where we store the pyx file. # This is deleted when Sage exits, which means pyx files must be # rebuilt every time Sage is restarted at present. target_dir = os.path.join(SPYX_TMP, base) # Build directory for Cython/distutils build_dir = os.path.join(target_dir, "build") if os.path.exists(target_dir): # There is already a module here. Maybe we do not have to rebuild? # Find the name. if use_cache: from sage.misc.sageinspect import loadable_module_extension prev_so = [F for F in os.listdir(target_dir) if F.endswith(loadable_module_extension())] if len(prev_so) > 0: prev_so = prev_so[0] # should have length 1 because of deletes below if os.path.getmtime(filename) <= os.path.getmtime('%s/%s'%(target_dir, prev_so)): # We do not have to rebuild. return prev_so[:-len(loadable_module_extension())], target_dir # Delete all ordinary files in target_dir for F in os.listdir(target_dir): G = os.path.join(target_dir, F) if os.path.isdir(G): continue try: os.unlink(G) except OSError: pass else: sage_makedirs(target_dir) if create_local_so_file: name = base else: global sequence_number if base not in sequence_number: sequence_number[base] = 0 name = '%s_%s'%(base, sequence_number[base]) # increment the sequence number so will use a different one next time. sequence_number[base] += 1 if compile_message: print("Compiling {}...".format(filename), file=sys.stderr) sys.stderr.flush() with open(filename) as f: (preparsed, libs, includes, language, additional_source_files, extra_args, libdirs) = _pyx_preparse(f.read()) # New filename with preparsed code. # NOTE: if we ever stop preparsing, we should still copy the # original file to the target directory. pyxfile = os.path.join(target_dir, name + ".pyx") with open(pyxfile, 'w') as f: f.write(preparsed) extra_sources = [] for fname in additional_source_files: fname = fname.replace("$SAGE_SRC", SAGE_SRC) fname = fname.replace("$SAGE_LOCAL", SAGE_LOCAL) extra_sources.append(fname) # Add current working directory to includes. This is needed because # we cythonize from a different directory. See Trac #24764. includes.insert(0, os.getcwd()) # Now do the actual build, directly calling Cython and distutils from Cython.Build import cythonize from Cython.Compiler.Errors import CompileError import Cython.Compiler.Options from distutils.dist import Distribution from distutils.core import Extension from distutils.log import set_verbosity set_verbosity(verbose) Cython.Compiler.Options.annotate = annotate Cython.Compiler.Options.embed_pos_in_docstring = True Cython.Compiler.Options.pre_import = "sage.all" if sage_namespace else None ext = Extension(name, sources=[pyxfile] + extra_sources, libraries=libs, library_dirs=[os.path.join(SAGE_LOCAL, "lib")] + libdirs, extra_compile_args=extra_args, language=language) try: # Change directories to target_dir so that Cython produces the correct # relative path; https://trac.sagemath.org/ticket/24097 with restore_cwd(target_dir): try: ext, = cythonize([ext], aliases=cython_aliases(), include_path=includes, quiet=(verbose <= 0), errors_to_stderr=False, use_listing_file=True) finally: # Read the "listing file" which is the file containing # warning and error messages generated by Cython. try: with open(name + ".lis") as f: cython_messages = f.read() except IOError: cython_messages = "Error compiling Cython file" except CompileError: # Check for names in old_pxi_names for pxd, names in old_pxi_names.items(): for name in names: if re.search(r"\b{}\b".format(name), cython_messages): cython_messages += dedent( """ NOTE: Sage no longer automatically includes the deprecated files "cdefs.pxi", "signals.pxi" and "stdsage.pxi" in Cython files. You can fix your code by adding "from {} cimport {}". """.format(pxd, name)) raise RuntimeError(cython_messages.strip()) if verbose >= 0: sys.stderr.write(cython_messages) sys.stderr.flush() if create_local_c_file: shutil.copy(os.path.join(target_dir, ext.sources[0]), os.curdir) if annotate: shutil.copy(os.path.join(target_dir, name + ".html"), os.curdir) # This emulates running "setup.py build" with the correct options dist = Distribution() dist.ext_modules = [ext] dist.include_dirs = includes buildcmd = dist.get_command_obj("build") buildcmd.build_base = build_dir buildcmd.build_lib = target_dir try: # Capture errors from distutils and its child processes with open(os.path.join(target_dir, name + ".err"), 'w+') as errfile: try: # Redirect stderr to errfile. We use the file descriptor # number "2" instead of "sys.stderr" because we really # want to redirect the messages from GCC. These are sent # to the actual stderr, regardless of what sys.stderr is. sys.stderr.flush() with redirection(2, errfile, close=False): dist.run_command("build") finally: errfile.seek(0) distutils_messages = errfile.read() except Exception as msg: msg = str(msg) + "\n" + distutils_messages raise RuntimeError(msg.strip()) if verbose >= 0: sys.stderr.write(distutils_messages) sys.stderr.flush() if create_local_so_file: # Copy module to current directory from sage.misc.sageinspect import loadable_module_extension shutil.copy(os.path.join(target_dir, name + loadable_module_extension()), os.curdir) return name, target_dir
def path(): from sage.misc.misc import sage_makedirs sage_makedirs(PATH)
import os from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import RationalField from sage.rings.arith import GCD import sage.misc.db as db from sage.misc.misc import SAGE_ROOT, sage_makedirs # TODO: # I messed up and now self.d is i and self.i is d, # i.e., the degree and number are swapped. PATH = SAGE_ROOT + "/src/tables/modular/gamma0/db/" sage_makedirs(PATH) class ModularForm: def __init__(self, N, d, i, Wq, r, charpolys, disc): self.N = N self.d = d self.i = i self.Wq = Wq self.r = r self.charpolys = charpolys self.disc = disc def __repr__(self): s = "Modular form: level %s, degree %s, number %s"%( self.N,self.d,self.i) + \ ", Wq: %s, an rank bnd: %s"%( self.Wq, self.r)