@@ -105,25 +105,38 @@ def import_statement_string(module, names, lazy):
105105 "lazy_import('sage.misc.dev_tools', 'import_statement_string', 'iss')"
106106 sage: dt.import_statement_string(modname, [('a','b'),('c','c'),('d','e')], False)
107107 'from sage.misc.dev_tools import a as b, c, d as e'
108+ sage: dt.import_statement_string(modname, [(None,None)], False)
109+ 'import sage.misc.dev_tools'
108110 """
109111 if lazy :
110112 if len (names ) == 1 :
111113 name , alias = names [0 ]
112114 if name == alias :
115+ if name is None :
116+ raise ValueError ("can not lazy import modules" )
113117 return "lazy_import('%s', '%s')" % (module , name )
114118 else :
115119 return "lazy_import('%s', '%s', '%s')" % (module , name , alias )
116120 obj_names = "[" + ", " .join ("'" + name [0 ] + "'" for name in names ) + "]"
117121 obj_aliases = "[" + ", " .join ("'" + name [1 ] + "'" for name in names ) + "]"
118122 return "lazy_import('%s', %s, %s)" % (module , obj_names , obj_aliases )
119123 else :
124+ import_module = False
120125 name_list = []
121126 for name ,alias in names :
122127 if name == alias :
128+ if name is None :
129+ import_module = True
130+ continue
123131 name_list .append (name )
124132 else :
125133 name_list .append ("%s as %s" % (name ,alias ))
126- return "from %s import %s" % (module , ', ' .join (name_list ))
134+ res = []
135+ if import_module :
136+ res .append ("import %s" % module )
137+ if name_list :
138+ res .append ("from %s import %s" % (module , ', ' .join (name_list )))
139+ return "\n " .join (res )
127140
128141def load_submodules (module = None , exclude_pattern = None ):
129142 r"""
@@ -278,8 +291,6 @@ def find_object_modules(obj):
278291 sage: find_object_modules(ZZ)
279292 {'sage.rings.integer_ring': ['Z', 'ZZ']}
280293
281- Here we test some instances::
282-
283294 .. NOTE::
284295
285296 It might be a good idea to move this function in
@@ -442,7 +453,7 @@ def import_statements(*objects, **options):
442453 sage: import_statements('EnumeratedSetFromIterator')
443454 Traceback (most recent call last):
444455 ...
445- ValueError: no object whose name matches 'EnumeratedSetFromIterator' was found.
456+ ValueError: no object matched by 'EnumeratedSetFromIterator' was found.
446457 sage: from sage.misc.dev_tools import load_submodules
447458 sage: load_submodules(sage.sets)
448459 load sage.sets.cartesian_product... suceeded
@@ -480,6 +491,10 @@ def import_statements(*objects, **options):
480491 from sage.symbolic.constants import NaN
481492 sage: import_statements(pi)
482493 from sage.symbolic.constants import pi
494+ sage: import_statements('SAGE_ENV')
495+ from sage.env import SAGE_ENV
496+ sage: import_statements('graph_decompositions')
497+ import sage.graphs.graph_decompositions
483498
484499 .. NOTE::
485500
@@ -491,9 +506,9 @@ def import_statements(*objects, **options):
491506 import inspect
492507 from sage .misc .lazy_import import LazyImport
493508
494- answer = {} # a dictionnary module -> things to be imported
495- # a value None is interpreted as the fact that it is the
496- # module that we want to import
509+ answer = {} # a dictionnary module -> [(name1,alias1), (name2,alias2) ...]
510+ # where "nameX" is an object in "module" that has to be
511+ # imported with the alias "aliasX"
497512
498513 lazy = options .pop ("lazy" , False )
499514 verbose = options .pop ("verbose" , True )
@@ -503,7 +518,9 @@ def import_statements(*objects, **options):
503518 raise ValueError ("Unexpected '%s' argument" % options .keys ()[0 ])
504519
505520 for obj in objects :
506- # if obj is a string use look for an object that goes by that name
521+ name = None # the name of the object
522+
523+ # 1. if obj is a string, we look for an object that has that name
507524 if isinstance (obj , str ):
508525 name = obj
509526 obj = find_objects_from_name (name , 'sage' )
@@ -531,17 +548,27 @@ def import_statements(*objects, **options):
531548 for module_name in modules :
532549 print "# - %s" % module_name
533550
551+ # choose a random object among the potentially enormous list of
552+ # objects we get from "name"
534553 obj = obj [0 ]
535554
536- else : # otherwise we need to fix the name later
537- name = None
538555
556+ # 1'. if obj is a LazyImport we recover the real object
539557 if isinstance (obj , LazyImport ):
540558 obj = obj ._get_object ()
541559
542- # easy case: the object is a module
560+
561+ # 2. Find out in which modules obj lives
562+ # and update answer with a couple of strings "(name,alias)" where "name" is
563+ # the name of the object in the module and "alias" is the name of the
564+ # object
565+
566+ # easy case: the object is itself a module
543567 if inspect .ismodule (obj ):
544- raise ValueError ("the object '%s' is a module" % obj )
568+ module_name = obj .__name__
569+ if module_name not in answer :
570+ answer [module_name ] = []
571+ answer [module_name ].append ((None ,None ))
545572 continue
546573
547574 modules = find_object_modules (obj )
@@ -551,7 +578,7 @@ def import_statements(*objects, **options):
551578 if not modules :
552579 raise ValueError ("no import statement found for '%s'." % obj )
553580
554- if len (modules ) == 1 :
581+ if len (modules ) == 1 : # the module is well defined
555582 module_name , obj_names = modules .items ()[0 ]
556583 if name is None :
557584 if verbose and len (obj_names ) > 1 :
@@ -569,7 +596,9 @@ def import_statements(*objects, **options):
569596 answer [module_name ].append ((name ,alias ))
570597 continue
571598
572- # here we get several answers
599+ # here modules contain several answers and we first try to see if there
600+ # is a best one (i.e. the object "obj" is contained in the module and
601+ # has name "name")
573602 if name is not None :
574603 good_modules = []
575604 for module_name in modules :
@@ -582,7 +611,8 @@ def import_statements(*objects, **options):
582611 answer [module_name ].append ((name ,name ))
583612 continue
584613
585- # if the object is a class instance, we might prefer use the .all
614+ # if the object is a class instance, it is likely that it is defined in
615+ # some XYZ.all module
586616 from sageinspect import isclassinstance
587617 if isclassinstance (obj ):
588618 module_name = type (obj ).__module__
@@ -595,6 +625,9 @@ def import_statements(*objects, **options):
595625 module_name = None
596626
597627 if module_name is None :
628+ # here, either "obj" is a class instance but there is no natural
629+ # candidate for its module or "obj" is not a class instance.
630+
598631 not_all_modules = [module_name for module_name in modules if not '.all_' in module_name and not module_name .endswith ('.all' )]
599632 if not (not_all_modules ):
600633 print "# ** Warning **: the object %s is only defined in .all modules" % obj
@@ -605,6 +638,7 @@ def import_statements(*objects, **options):
605638 print "# ** Warning **: several modules for the object %s: %s" % (obj , ', ' .join (modules .keys ()))
606639 module_name = not_all_modules [0 ]
607640
641+ # 3. Now that we found the module, we fix the problem of the alias
608642 if name is None :
609643 alias = name = modules [module_name ][0 ]
610644 else :
0 commit comments