Load Python, Sage, Cython, Fortran and Magma files in Sage - The Sage Command Line

Skip to content
Back to top
View this page
Edit this page

# Load Python, Sage, Cython, Fortran and Magma files in Sage

sage.repl.load.is_loadable_filename(filename)

  Return whether a file can be loaded into Sage.

  This checks only whether its name ends in one of the supported extensions `.py`, `.pyx`, `.sage`, `.spyx`, `.f`, `.f90` and `.m`.

  Note

  `load()` assumes that \(.m\) signifies a Magma file.

  INPUT:

  - `filename` – string or `Path` object

  OUTPUT: boolean

  EXAMPLES:

  Sage

      sage: sage.repl.load.is_loadable_filename('foo.bar')
      False
      sage: sage.repl.load.is_loadable_filename('foo.c')
      False
      sage: sage.repl.load.is_loadable_filename('foo.sage')
      True
      sage: sage.repl.load.is_loadable_filename('FOO.F90')
      True
      sage: sage.repl.load.is_loadable_filename('foo.m')
      True

      sage: from pathlib import Path
      sage: sage.repl.load.is_loadable_filename(Path('foo.py'))
      True

  Python

      >>> from sage.all import *
      >>> sage.repl.load.is_loadable_filename('foo.bar')
      False
      >>> sage.repl.load.is_loadable_filename('foo.c')
      False
      >>> sage.repl.load.is_loadable_filename('foo.sage')
      True
      >>> sage.repl.load.is_loadable_filename('FOO.F90')
      True
      >>> sage.repl.load.is_loadable_filename('foo.m')
      True

      >>> from pathlib import Path
      >>> sage.repl.load.is_loadable_filename(Path('foo.py'))
      True

sage.repl.load.load(filename, globals, attach=False)

  Execute a file in the scope given by `globals`. If the name starts with `http://` or `https://`, it is treated as a URL and downloaded.

  Note

  For Cython files, the situation is more complicated – the module is first compiled to a temporary module `t` and executed via:

      from t import *

  Note

  The global `load` function is `sage.misc.persist.load()`, which delegates to this function for code file formats.

  `%runfile` magic can also be used, see `runfile()`.

  INPUT:

  - `filename` – string (denoting a filename or URL) or a `Path` object

  - `globals` – string:object dictionary; the context in which to execute the file contents

  - `attach` – boolean (default: `False`); whether to add the file to the list of attached files

  Loading an executable Sage script from the command line will run whatever code is inside an

      if __name__ == "__main__":

  section, as the condition on `__name__` will hold true (code run from the command line is considered to be running in the `__main__` module.)

  EXAMPLES:

  Note that `.py` files are not preparsed:

  Sage

      sage: from tempfile import NamedTemporaryFile
      sage: context = { "z": 1}
      sage: with NamedTemporaryFile(mode='w', suffix='.py') as file:
      ....:     _ = file.write("print(('hi', 2^3, z)); z = -2^7")
      ....:     _ = file.seek(0)
      ....:     sage.repl.load.load(file.name, context)
      ('hi', 1, 1)
      sage: context["z"]
      -7

  Python

      >>> from sage.all import *
      >>> from tempfile import NamedTemporaryFile
      >>> context = { "z": Integer(1)}
      >>> with NamedTemporaryFile(mode='w', suffix='.py') as file:
      ...     _ = file.write("print(('hi', 2^3, z)); z = -2^7")
      ...     _ = file.seek(Integer(0))
      ...     sage.repl.load.load(file.name, context)
      ('hi', 1, 1)
      >>> context["z"]
      -7

  A `.sage` file is preparsed:

  Sage

      sage: context = { "z": 1, "Integer": Integer }
      sage: with NamedTemporaryFile(mode='w', suffix='.sage') as file:
      ....:     _ = file.write("print(('hi', 2^3, z)); z = -2^7")
      ....:     _ = file.seek(0)
      ....:     sage.repl.load.load(file.name, context)
      ('hi', 8, 1)
      sage: context["z"]
      -128

  [Python]

      >>> from sage.all import *
      >>> context = { "z": Integer(1), "Integer": Integer }
      >>> with NamedTemporaryFile(mode='w', suffix='.sage') as file:
      ...     _ = file.write("print(('hi', 2^3, z)); z = -2^7")
      ...     _ = file.seek(Integer(0))
      ...     sage.repl.load.load(file.name, context)
      ('hi', 8, 1)
      >>> context["z"]
      -128

  Cython files are not preparsed:

  Sage

      sage: context = { "z": 1 }
      sage: with NamedTemporaryFile(mode='w', suffix='.pyx') as file:
      ....:     _ = file.write("print(('hi', 2^3)); z = -2^7")
      ....:     _ = file.seek(0)
      ....:     sage.repl.load.load(file.name, context)                                         # needs sage.misc.cython
      Compiling ...
      ('hi', 1)
      sage: context["z"]
      -7

  Python

      >>> from sage.all import *
      >>> context = { "z": Integer(1) }
      >>> with NamedTemporaryFile(mode='w', suffix='.pyx') as file:
      ...     _ = file.write("print(('hi', 2^3)); z = -2^7")
      ...     _ = file.seek(Integer(0))
      ...     sage.repl.load.load(file.name, context)                                         # needs sage.misc.cython
      Compiling ...
      ('hi', 1)
      >>> context["z"]
      -7

  If the file is not a Cython, Python, or Sage file, a `ValueError` is raised:

  Sage

      sage: with NamedTemporaryFile(mode='w', suffix='.foo') as file:
      ....:     sage.repl.load.load(file.name, {})
      Traceback (most recent call last):
      ...
      ValueError: unknown file extension '.foo' for load or attach (supported extensions: .py, .pyx, .sage, .spyx, .f, .f90, .m)

  [Python]

      >>> from sage.all import *
      >>> with NamedTemporaryFile(mode='w', suffix='.foo') as file:
      ...     sage.repl.load.load(file.name, {})
      Traceback (most recent call last):
      ...
      ValueError: unknown file extension '.foo' for load or attach (supported extensions: .py, .pyx, .sage, .spyx, .f, .f90, .m)

  We load a file given at a remote URL (not tested for security reasons):

  Sage

      sage: sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals())  # not tested
      hi from the net
      5

  Python

      >>> from sage.all import *
      >>> sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals())  # not tested
      hi from the net
      5

  We can load files using secure http (https):

  Sage

      sage: sage.repl.load.load('https://raw.githubusercontent.com/sagemath/sage-patchbot/3.0.0/sage_patchbot/util.py', globals())  # optional - internet

  [Python]

      >>> from sage.all import *
      >>> sage.repl.load.load('https://raw.githubusercontent.com/sagemath/sage-patchbot/3.0.0/sage_patchbot/util.py', globals())  # optional - internet

  We attach a file (note that `attach()` is equivalent, but available at the global scope by default):

  Sage

      sage: with NamedTemporaryFile(mode='w', suffix='.py') as file:
      ....:     _ = file.write("print('hello world')")
      ....:     _ = file.seek(0)
      ....:     sage.repl.load.load(file.name, {}, attach=True)
      hello world
      sage: file.name in attached_files()
      True

  Python

      >>> from sage.all import *
      >>> with NamedTemporaryFile(mode='w', suffix='.py') as file:
      ...     _ = file.write("print('hello world')")
      ...     _ = file.seek(Integer(0))
      ...     sage.repl.load.load(file.name, {}, attach=True)
      hello world
      >>> file.name in attached_files()
      True

  You cannot attach remote URLs (yet):

  Sage

      sage: sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals(), attach=True)  # optional - internet
      Traceback (most recent call last):
      ...
      NotImplementedError: you cannot attach a URL

  [Python]

      >>> from sage.all import *
      >>> sage.repl.load.load('https://www.sagemath.org/files/loadtest.py', globals(), attach=True)  # optional - internet
      Traceback (most recent call last):
      ...
      NotImplementedError: you cannot attach a URL

  The default search path for loading and attaching files is the current working directory, i.e., `'.'`. But you can modify the path with `load_attach_path()`:

  Sage

      sage: import tempfile
      sage: sage.repl.attach.reset(); reset_load_attach_path()
      sage: load_attach_path()
      [PosixPath('.')]
      sage: with tempfile.TemporaryDirectory() as t_dir:
      ....:     fname = 'test.py'
      ....:     fullpath = os.path.join(t_dir, fname)
      ....:     with open(fullpath, 'w') as f:
      ....:         _ = f.write("print(37 * 3)")
      ....:     load_attach_path(t_dir, replace=True)
      ....:     attach(fname)
      111
      sage: sage.repl.attach.reset(); reset_load_attach_path() # clean up

  Python

      >>> from sage.all import *
      >>> import tempfile
      >>> sage.repl.attach.reset(); reset_load_attach_path()
      >>> load_attach_path()
      [PosixPath('.')]
      >>> with tempfile.TemporaryDirectory() as t_dir:
      ...     fname = 'test.py'
      ...     fullpath = os.path.join(t_dir, fname)
      ...     with open(fullpath, 'w') as f:
      ...         _ = f.write("print(37 * 3)")
      ...     load_attach_path(t_dir, replace=True)
      ...     attach(fname)
      111
      >>> sage.repl.attach.reset(); reset_load_attach_path() # clean up

  or by setting the environment variable `SAGE_LOAD_ATTACH_PATH` to a colon-separated list before starting Sage:

      $ export SAGE_LOAD_ATTACH_PATH="/path/to/my/library:/path/to/utils"
      $ sage
      sage: load_attach_path()          # not tested
      ['.', '/path/to/my/library', '/path/to/utils']

sage.repl.load.load_cython(name)

  Helper function to load a Cython file.

  INPUT:

  - `name` – filename of the Cython file

  OUTPUT:

  - A string with Python code to import the names from the compiled module.

sage.repl.load.load_wrap(filename, attach=False)

  Encode a load or attach command as valid Python code.

  INPUT:

  - `filename` – string or `Path` object; the argument to the load or attach command

  - `attach` – boolean (default: `False`); whether to attach `filename`, instead of loading it

  OUTPUT: string

  EXAMPLES:

  Sage

      sage: sage.repl.load.load_wrap('foo.py', True)
      'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnB5"),globals(),True)'
      sage: sage.repl.load.load_wrap('foo.sage')
      'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnNhZ2U="),globals(),False)'
      sage: m = sage.repl.load.base64.b64decode("Zm9vLnNhZ2U=")
      sage: m == b'foo.sage'
      True

  Python

      >>> from sage.all import *
      >>> sage.repl.load.load_wrap('foo.py', True)
      'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnB5"),globals(),True)'
      >>> sage.repl.load.load_wrap('foo.sage')
      'sage.repl.load.load(sage.repl.load.base64.b64decode("Zm9vLnNhZ2U="),globals(),False)'
      >>> m = sage.repl.load.base64.b64decode("Zm9vLnNhZ2U=")
      >>> m == b'foo.sage'
      True