Ask Your Question

Revision history [back]

Here is a patch to apply (the trac server is not responding at the moment — once it is, I will post there, too):

diff --git a/src/bin/sage-preparse b/src/bin/sage-preparse
index 2d87e73dca..5103fe657b 100755
--- a/src/bin/sage-preparse
+++ b/src/bin/sage-preparse
@@ -61,6 +61,7 @@ AUTOGEN_MSG = "# This file was *autogenerated* from the file "
 # We want to save the leading white space so that we can maintain
 # correct indentation in the preparsed file.
 load_or_attach = re.compile(r"^(?P<lws>\s*)(load|attach)\s+(?P<files>.*)$")
+future_imports = re.compile("^\s*(from __future__ import .*)$")

 def do_preparse(f, files_before=[]):
     """
@@ -126,6 +127,12 @@ def do_preparse(f, files_before=[]):
     # Preparse the body
     body = preparse_file(body)

+    # Check for "from __future__ import ..." statements. Those
+    # statements need to come at the top of the file (after the
+    # module-level docstring is okay), so we separate them from the
+    # body.
+    future_imports, body = find_future_imports(body)
+
     # Check for load/attach commands.
     body = do_load_and_attach(body, f, files_before)

@@ -138,6 +145,8 @@ def do_preparse(f, files_before=[]):
         f.write(coding)
         f.write(header)
         f.write('\n')
+        f.write(future_imports)
+        f.write('\n')
         f.write(sage_incl)
         f.write('\n')
         f.write(body)
@@ -196,6 +205,26 @@ def find_position_right_after_module_docstring(G):
         return pos_after_line(i)


+def find_future_imports(G):
+    """
+    Parse a file G, looking for "from __future import ...".
+
+    Return a tuple: (the import statements, the file G with those
+    statements removed)
+
+    INPUT:
+        G -- a string; a file loaded in from disk
+    """
+    import_statements = ''
+    new_G = ''
+    for t in G.split('\n'):
+        z = future_imports.match(t)
+        if z:
+            import_statements += z.group(1) + '\n'
+        else:
+            new_G += t + '\n'
+    return (import_statements, new_G)
+

 def do_load_and_attach(G, file, files_before):
     """

Here is a patch posted to apply (the trac server is not responding at the moment — once it is, I will post there, too):https://trac.sagemath.org/ticket/27719:

diff --git a/src/bin/sage-preparse b/src/bin/sage-preparse
index 2d87e73dca..5103fe657b 100755
--- a/src/bin/sage-preparse
+++ b/src/bin/sage-preparse
@@ -61,6 +61,7 @@ AUTOGEN_MSG = "# This file was *autogenerated* from the file "
 # We want to save the leading white space so that we can maintain
 # correct indentation in the preparsed file.
 load_or_attach = re.compile(r"^(?P<lws>\s*)(load|attach)\s+(?P<files>.*)$")
+future_imports = re.compile("^\s*(from __future__ import .*)$")

 def do_preparse(f, files_before=[]):
     """
@@ -126,6 +127,12 @@ def do_preparse(f, files_before=[]):
     # Preparse the body
     body = preparse_file(body)

+    # Check for "from __future__ import ..." statements. Those
+    # statements need to come at the top of the file (after the
+    # module-level docstring is okay), so we separate them from the
+    # body.
+    future_imports, body = find_future_imports(body)
+
     # Check for load/attach commands.
     body = do_load_and_attach(body, f, files_before)

@@ -138,6 +145,8 @@ def do_preparse(f, files_before=[]):
         f.write(coding)
         f.write(header)
         f.write('\n')
+        f.write(future_imports)
+        f.write('\n')
         f.write(sage_incl)
         f.write('\n')
         f.write(body)
@@ -196,6 +205,26 @@ def find_position_right_after_module_docstring(G):
         return pos_after_line(i)


+def find_future_imports(G):
+    """
+    Parse a file G, looking for "from __future import ...".
+
+    Return a tuple: (the import statements, the file G with those
+    statements removed)
+
+    INPUT:
+        G -- a string; a file loaded in from disk
+    """
+    import_statements = ''
+    new_G = ''
+    for t in G.split('\n'):
+        z = future_imports.match(t)
+        if z:
+            import_statements += z.group(1) + '\n'
+        else:
+            new_G += t + '\n'
+    return (import_statements, new_G)
+

 def do_load_and_attach(G, file, files_before):
     """

Here is a patch posted to https://trac.sagemath.org/ticket/27719:https://trac.sagemath.org/ticket/27719 (plus I added a doctest there, too):

diff --git a/src/bin/sage-preparse b/src/bin/sage-preparse
index 2d87e73dca..5103fe657b 100755
--- a/src/bin/sage-preparse
+++ b/src/bin/sage-preparse
@@ -61,6 +61,7 @@ AUTOGEN_MSG = "# This file was *autogenerated* from the file "
 # We want to save the leading white space so that we can maintain
 # correct indentation in the preparsed file.
 load_or_attach = re.compile(r"^(?P<lws>\s*)(load|attach)\s+(?P<files>.*)$")
+future_imports = re.compile("^\s*(from __future__ import .*)$")

 def do_preparse(f, files_before=[]):
     """
@@ -126,6 +127,12 @@ def do_preparse(f, files_before=[]):
     # Preparse the body
     body = preparse_file(body)

+    # Check for "from __future__ import ..." statements. Those
+    # statements need to come at the top of the file (after the
+    # module-level docstring is okay), so we separate them from the
+    # body.
+    future_imports, body = find_future_imports(body)
+
     # Check for load/attach commands.
     body = do_load_and_attach(body, f, files_before)

@@ -138,6 +145,8 @@ def do_preparse(f, files_before=[]):
         f.write(coding)
         f.write(header)
         f.write('\n')
+        f.write(future_imports)
+        f.write('\n')
         f.write(sage_incl)
         f.write('\n')
         f.write(body)
@@ -196,6 +205,26 @@ def find_position_right_after_module_docstring(G):
         return pos_after_line(i)


+def find_future_imports(G):
+    """
+    Parse a file G, looking for "from __future import ...".
+
+    Return a tuple: (the import statements, the file G with those
+    statements removed)
+
+    INPUT:
+        G -- a string; a file loaded in from disk
+    """
+    import_statements = ''
+    new_G = ''
+    for t in G.split('\n'):
+        z = future_imports.match(t)
+        if z:
+            import_statements += z.group(1) + '\n'
+        else:
+            new_G += t + '\n'
+    return (import_statements, new_G)
+

 def do_load_and_attach(G, file, files_before):
     """