def attach(self, s): r""" Attaches the code contained in the file ``s``. This is designed to be used from the command line as ``%attach /path/to/file``. :param s: file to be attached :type s: string EXAMPLES:: sage: import os sage: from sage.misc.interpreter import get_test_shell sage: shell = get_test_shell() sage: tmp = os.path.normpath(os.path.join(SAGE_TMP, 'run_cell.py')) sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close() sage: shell.run_cell('%attach ' + tmp) sage: shell.run_cell('a') 2 sage: import time; time.sleep(1) sage: f = open(tmp, 'w'); f.write('a = 3\n'); f.close() sage: shell.run_cell('a') 3 sage: shell.run_cell('detach(%r)'%tmp) sage: shell.run_cell('attached_files()') [] sage: os.remove(tmp) """ from sage.misc.preparser import load_wrap return self.shell.ex(load_wrap(s, attach=True))
def reload_attached_files_if_modified(): """ Reload attached files that have been modified This is the internal implementation of the attach mechanism. EXAMPLES:: sage: sage.misc.attached_files.reset() sage: from sage.repl.interpreter import get_test_shell sage: shell = get_test_shell() sage: tmp = tmp_filename(ext='.py') sage: open(tmp, 'w').write('a = 2\n') sage: shell.run_cell('attach({0})'.format(repr(tmp))) sage: shell.run_cell('a') 2 sage: sleep(1) # filesystem mtime granularity sage: open(tmp, 'w').write('a = 3\n') Note that the doctests are never really at the command prompt where the automatic reload is triggered. So we have to do it manually:: sage: shell.run_cell('from sage.misc.attached_files import reload_attached_files_if_modified') sage: shell.run_cell('reload_attached_files_if_modified()') ### reloading attached file tmp_....py modified at ... ### sage: shell.run_cell('a') 3 sage: shell.run_cell('detach({0})'.format(repr(tmp))) sage: shell.run_cell('attached_files()') [] """ for filename, mtime in modified_file_iterator(): basename = os.path.basename(filename) timestr = time.strftime('%T', mtime) from sage.libs.readline import interleaved_output with interleaved_output(): print('### reloading attached file {0} modified at {1} ###'.format( basename, timestr)) code = load_wrap(filename, attach=True) get_ipython().run_cell(code)
def reload_attached_files_if_modified(): """ Reload attached files that have been modified This is the internal implementation of the attach mechanism. EXAMPLES:: sage: sage.misc.attached_files.reset() sage: from sage.misc.interpreter import get_test_shell sage: shell = get_test_shell() sage: tmp = tmp_filename(ext='.py') sage: open(tmp, 'w').write('a = 2\n') sage: shell.run_cell('attach({0})'.format(repr(tmp))) sage: shell.run_cell('a') 2 sage: sleep(1) # filesystem mtime granularity sage: open(tmp, 'w').write('a = 3\n') Note that the doctests are never really at the command prompt where the automatic reload is triggered. So we have to do it manually:: sage: shell.run_cell('from sage.misc.attached_files import reload_attached_files_if_modified') sage: shell.run_cell('reload_attached_files_if_modified()') ### reloading attached file tmp_....py modified at ... ### sage: shell.run_cell('a') 3 sage: shell.run_cell('detach({0})'.format(repr(tmp))) sage: shell.run_cell('attached_files()') [] """ for filename, mtime in modified_file_iterator(): basename = os.path.basename(filename) timestr = time.strftime('%T', mtime) from sage.libs.readline import interleaved_output with interleaved_output(): print '### reloading attached file {0} modified at {1} ###'.format(basename, timestr) code = load_wrap(filename, attach=True) get_ipython().run_cell(code)
def attach(self, s): r""" Attaches the code contained in the file ``s``. This is designed to be used from the command line as ``%attach /path/to/file``. :param s: file to be attached :type s: string EXAMPLES:: sage: import os sage: from sage.misc.interpreter import get_test_shell sage: shell = get_test_shell() sage: tmp = os.path.normpath(os.path.join(SAGE_TMP, 'run_cell.py')) sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close() sage: shell.run_cell('%attach ' + tmp) sage: shell.run_cell('a') 2 sage: sleep(1) # filesystem timestamp granularity sage: f = open(tmp, 'w'); f.write('a = 3\n'); f.close() Note that the doctests are never really at the command prompt, so we call the input hook manually:: sage: shell.run_cell('from sage.misc.inputhook import sage_inputhook') sage: shell.run_cell('sage_inputhook()') ### reloading attached file run_cell.py modified at ... ### 0 sage: shell.run_cell('a') 3 sage: shell.run_cell('detach(%r)'%tmp) sage: shell.run_cell('attached_files()') [] sage: os.remove(tmp) """ from sage.misc.preparser import load_wrap return self.shell.ex(load_wrap(s, attach=True))
def runfile(self, s): r""" Loads the code contained in the file ``s``. This is designed to be used from the command line as ``%runfile /path/to/file``. :param s: file to be loaded :type s: string EXAMPLES:: sage: import os sage: from sage.misc.interpreter import get_test_shell sage: from sage.misc.misc import tmp_dir sage: shell = get_test_shell() sage: tmp = os.path.join(tmp_dir(), 'run_cell.py') sage: f = open(tmp, 'w'); f.write('a = 2\n'); f.close() sage: shell.run_cell('%runfile '+tmp) sage: shell.run_cell('a') 2 """ from sage.misc.preparser import load_wrap return self.shell.ex(load_wrap(s, attach=False))
def attach(*files): """ Attach a file or files to a running instance of Sage and also load that file. USAGE: ``attach file1 ...`` - space-separated list of ``.py``, ``.pyx``, and ``.sage`` files, or ``attach('file1', 'file2')`` - filenames as strings, given as arguments to :func:`attach`. :meth:`~sage.misc.preparser.load` is the same as :func:`attach`, but doesn't automatically reload a file when it changes. .. NOTE:: On the Sage prompt you can also just type ``attach "foo.sage"`` as a short-hand for ``attach('foo.sage')``. However this alternate form is not part of the Python language and does not work in Python scripts. EFFECT: Each file is read in and added to an internal list of watched files. The meaning of reading in a file depends on the file type: - ``.py`` files are read in with no preparsing (so, e.g., ``2^3`` is 2 bit-xor 3); - ``.sage`` files are preparsed, then the result is read in; - ``.pyx`` files are *not* preparsed, but rather are compiled to a module ``m`` and then ``from m import *`` is executed. The contents of the file are then loaded, which means they are read into the running Sage session. For example, if ``foo.sage`` contains ``x=5``, after attaching ``foo.sage`` the variable ``x`` will be set to 5. Moreover, any time you change ``foo.sage``, before you execute a command, the attached file will be re-read automatically (with no intervention on your part). EXAMPLES: You attach a file, e.g., ``foo.sage`` or ``foo.py`` or ``foo.pyx``, to a running Sage session by typing:: sage: attach foo.sage # or foo.py or foo.pyx or even a URL to such a file (not tested) or:: sage: attach('foo.sage') # not tested Here we test attaching multiple files at once:: sage: sage.misc.attached_files.reset() sage: t1 = tmp_filename(ext='.py') sage: open(t1,'w').write("print 'hello world'") sage: t2 = tmp_filename(ext='.py') sage: open(t2,'w').write("print 'hi there xxx'") sage: attach(t1, t2) hello world hi there xxx sage: set(attached_files()) == set([t1,t2]) True .. SEEALSO:: - :meth:`attached_files` returns a list of all currently attached files. - :meth:`detach` instructs Sage to remove a file from the internal list of watched files. - :meth:`load_attach_path` allows you to get or modify the current search path for loading and attaching files. """ try: ipy = get_ipython() except NameError: ipy = None global attached for filename in files: if ipy: code = load_wrap(filename, attach=True) ipy.run_cell(code) else: load(filename, globals(), attach=True)