def refresh_model(self): """ Refresh the compiled model object. This method will (re)compile the model for the given model text and update the 'compiled_model' attribute. If a compiled view is available and has a member named 'model', the model will be applied to the view. """ text = self.model_text filename = self.model_filename _fake_linecache(text, filename) try: if not text: self.compiled_model = None self._model_module = None else: code = compile(text, filename, 'exec') module = ModuleType(filename.rsplit('.', 1)[0]) module.__file__ = filename namespace = module.__dict__ exec_(code, namespace) model = namespace.get(self.model_item, lambda: None)() self.compiled_model = model self._model_module = module self.relink_view() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def exec_entry(string, seq_locals, missing_locals): """ """ aux_strings = string.split("{") if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split("}")] missing = [el for el in elements[1::2] if el not in seq_locals] if missing: missing_locals.update(set(missing)) return None replacement_token = ["_a{}".format(i) for i in xrange(len(elements[1::2]))] replacement_values = {"_a{}".format(i): seq_locals[key] for i, key in enumerate(elements[1::2])} str_to_eval = "".join(key + "{}" for key in elements[::2]) str_to_eval = str_to_eval[:-2] expr = str_to_eval.format(*replacement_token) else: replacement_values = {} expr = string exec_(expr, locs=replacement_values) return locals()
def install(self, package, first=False): from future.utils import exec_ script = self.find_package_script(self.indexes, package) if script: script, code = script else: if first: self.message("Can't find the installation script of package %s" % (Fore.GREEN+Style.BRIGHT+package), 'error') return else: raise Error("Can't find the installation script of package %s" % package) self.message("Installing package %s" % (Fore.GREEN+package), 'install') try: d = self.make_env(script, code) c_code = compile(code, script, 'exec', dont_inherit=True) exec_(c_code, d) self.message("Installing package %s completed." % package, 'info') flag = True except Exception as e: flag = False if self.verbose: type, value, tb = sys.exc_info() txt = ''.join(traceback.format_exception(type, value, tb)) print (txt) if first: self.message("Installing package %s failed." % package, 'error') else: raise
def _importtestmodule(self): # We have to remove the __future__ statements *before* parsing # with compile, otherwise the flags are ignored. content = re.sub(_RE_FUTURE_IMPORTS, b'\n', self.content) new_mod = types.ModuleType(self.mod_name) new_mod.__file__ = text_to_native_str(self.fspath) if hasattr(self, '_transform_ast'): # ast.parse doesn't let us hand-select the __future__ # statements, but built-in compile, with the PyCF_ONLY_AST # flag does. tree = compile( content, text_to_native_str(self.fspath), 'exec', self.flags | ast.PyCF_ONLY_AST, True) tree = self._transform_ast(tree) # Now that we've transformed the tree, recompile it code = compile( tree, text_to_native_str(self.fspath), 'exec') else: # If we don't need to transform the AST, we can skip # parsing/compiling in two steps code = compile( content, text_to_native_str(self.fspath), 'exec', self.flags, True) pwd = os.getcwd() try: os.chdir(os.path.dirname(text_to_native_str(self.fspath))) exec_(code, new_mod.__dict__) finally: os.chdir(pwd) self.config.pluginmanager.consider_module(new_mod) return new_mod
def refresh_view(self, change): """ Refresh the compiled view object. This method will (re)compile the view for the given view text and update the 'compiled_view' attribute. If a compiled model is available and the view has a member named 'model', the model will be applied to the view. """ viewer = self.workbench.get_plugin('declaracad.viewer') doc = self.active_document try: ast = parse(doc.source, filename=doc.name) code = EnamlCompiler.compile(ast, doc.name) module = ModuleType('__main__') module.__file__ = doc.name namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) assembly = namespace.get('Assembly', lambda: None)() viewer.parts = [assembly] if assembly else [] except Exception as e: errors = doc.errors[:] log.warning(traceback.format_exc()) tb = traceback.format_exc().strip().split("\n") print(tb[-3]) m = re.search(r'File "(.+)", line (\d+),', tb[-3]) if m: errors.append("{}:{}: {}".format(m.group(1), m.group(2), tb[-1])) doc.errors = errors viewer.parts = []
def exec_entry(string, seq_locals, missing_locals): """ """ aux_strings = string.split('{') if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split('}')] missing = [el for el in elements[1::2] if el not in seq_locals] if missing: missing_locals.update(set(missing)) return None replacement_values = list({ '_a{}'.format(i): seq_locals[key] for i, key in enumerate(elements[1::2]) }.values()) str_to_eval = ''.join(key + '{}' for key in elements[::2]) str_to_eval = str_to_eval[:-2] expr = str_to_eval.format(*replacement_values) else: expr = string exec_(expr) return locals()
def compile_source(source, item, filename='<test>', namespace=None): """ Compile Enaml source code and return the target item. Parameters ---------- source : str The Enaml source code string to compile. item : str The name of the item in the resulting namespace to return. filename : str, optional The filename to use when compiling the code. The default is '<test>'. namespace : dict Namespace in which to execute the code Returns ------- result : object The named object from the resulting namespace. """ ast = parse(source, filename) code = EnamlCompiler.compile(ast, filename) namespace = namespace or {} exec_(code, namespace) return namespace[item]
def load_module(self, fullname): """ Loads and returns the Python module for the given enaml path. If a module already exisist in sys.path, the existing module is reused, otherwise a new one is created. """ code, path = self.get_code() if fullname in sys.modules: pre_exists = True mod = sys.modules[fullname] else: pre_exists = False mod = sys.modules[fullname] = types.ModuleType(fullname) mod.__loader__ = self mod.__file__ = path # Even though the import hook is already installed, this is a # safety net to avoid potentially hard to find bugs if code has # manually installed and removed a hook. The contract here is # that the import hooks are always installed when executing the # module code of an Enaml file. try: with imports(): exec_(code, mod.__dict__) except Exception: if not pre_exists: del sys.modules[fullname] raise return mod
def _importtestmodule(self): # We have to remove the __future__ statements *before* parsing # with compile, otherwise the flags are ignored. content = re.sub(_RE_FUTURE_IMPORTS, b'\n', self.content) new_mod = types.ModuleType(self.mod_name) new_mod.__file__ = text_to_native_str(self.fspath) if hasattr(self, '_transform_ast'): # ast.parse doesn't let us hand-select the __future__ # statements, but built-in compile, with the PyCF_ONLY_AST # flag does. tree = compile(content, text_to_native_str(self.fspath), 'exec', self.flags | ast.PyCF_ONLY_AST, True) tree = self._transform_ast(tree) # Now that we've transformed the tree, recompile it code = compile(tree, text_to_native_str(self.fspath), 'exec') else: # If we don't need to transform the AST, we can skip # parsing/compiling in two steps code = compile(content, text_to_native_str(self.fspath), 'exec', self.flags, True) pwd = os.getcwd() try: os.chdir(os.path.dirname(text_to_native_str(self.fspath))) exec_(code, new_mod.__dict__) finally: os.chdir(pwd) self.config.pluginmanager.consider_module(new_mod) return new_mod
def run(): """Initialise Talisker then exec python script.""" initialise() logger = logging.getLogger('talisker.run') name = sys.argv[0] if '__main__.py' in name: # friendlier message name = '{} -m talisker'.format(sys.executable) extra = {} try: if len(sys.argv) < 2: raise RunException('usage: {} <script> ...'.format(name)) script = sys.argv[1] extra['script'] = script with open(script, 'rb') as f: code = compile(f.read(), script, 'exec') # pretend we just invoked python script.py by mimicing usual python # behavior sys.path.insert(0, os.path.dirname(script)) sys.argv = sys.argv[1:] globs = {} globs['__file__'] = script globs['__name__'] = '__main__' globs['__package__'] = None exec_(code, globs, None) except Exception: logger.exception('Unhandled exception', extra=extra) sys.exit(1)
def execfile(filename, myglobals=None, mylocals=None): """ A version of execfile() that handles unicode filenames. From IPython. WARNING: This doesn't seem to work. We may need to use inspect to get the globals and locals dicts from the calling context. """ mylocals = mylocals if (mylocals is not None) else myglobals exec_(compile(open(filename).read(), filename, 'exec'), myglobals, mylocals)
def test_unicode_identifier(): source = dedent("""\ from enaml.widgets.api import Window enamldef MyWindow(Window): win: attr 𠁒 = 'test' # Check we do not mistake this for an invalid identifier attr a = 1.e6 """) myWindow = compile_source(source, 'MyWindow')() exec_("𠁒 = 'test'") assert locals()['𠁒'] == getattr(myWindow, """𠁒""")
def main(): usage = 'usage: %prog [options] enaml_file [script arguments]' parser = optparse.OptionParser(usage=usage, description=__doc__) parser.allow_interspersed_args = False parser.add_option('-c', '--component', default='Main', help='The component to view') options, args = parser.parse_args() if len(args) == 0: print('No .enaml file specified') sys.exit() else: enaml_file = args[0] script_argv = args[1:] with open(enaml_file, 'rU') as f: enaml_code = f.read() # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning module = types.ModuleType('__main__') module.__file__ = os.path.abspath(enaml_file) sys.modules['__main__'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) # Bung in the command line arguments. sys.argv = [enaml_file] + script_argv with imports(): exec_(code, ns) requested = options.component if requested in ns: from enaml.qt.qt_application import QtApplication app = QtApplication() window = ns[requested]() window.show() window.send_to_front() app.start() elif 'main' in ns: ns['main']() else: msg = "Could not find component '%s'" % options.component print(msg)
def _build_checker(self, check, set=False): """Assemble a checker function from the provided assertions. Parameters ---------- check : unicode ; separated string containing boolean test to assert. '{' and '}' delimit field which should be replaced by instrument state. 'value' should be considered a reserved keyword available when checking a set operation. Returns ------- checker : function Function to use """ func_def = 'def check(self, instance):\n' if not set\ else 'def check(self, instance, value):\n' assertions = check.split(';') for assertion in assertions: # First find replacement fields. aux = assertion.split('{') if len(aux) < 2: # Silently ignore checks unrelated to instrument state. continue line = 'assert ' els = [el.strip() for s in aux for el in s.split('}')] for i in range(0, len(els), 2): e = els[i] if i+1 < len(els): line += e + ' getattr(instance, "{}") '.format(els[i+1]) else: line += e values = ', '.join(('getattr(instance, "{}")'.format(el) for el in els[1::2])) val_fmt = ', '.join(('{}'.format(el)+'={}' for el in els[1::2])) a_mess = 'assertion {} failed, '.format(' '.join(els).strip()) a_mess += 'values are : {}".format(self.name, {})'.format(val_fmt, values) if set: a_mess = '"Setting {} ' + a_mess else: a_mess = '"Getting {} ' + a_mess func_def += ' ' + line + ', ' + a_mess + '\n' loc = {} exec_(func_def, locs=loc) return loc['check']
def main(): usage = 'usage: %prog [options] enaml_file [script arguments]' parser = optparse.OptionParser(usage=usage, description=__doc__) parser.allow_interspersed_args = False parser.add_option( '-c', '--component', default='Main', help='The component to view' ) options, args = parser.parse_args() if len(args) == 0: print('No .enaml file specified') sys.exit() else: enaml_file = args[0] script_argv = args[1:] with open(enaml_file, 'rU') as f: enaml_code = f.read() # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning module = types.ModuleType('__main__') module.__file__ = os.path.abspath(enaml_file) sys.modules['__main__'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) # Bung in the command line arguments. sys.argv = [enaml_file] + script_argv with imports(): exec_(code, ns) requested = options.component if requested in ns: from enaml.qt.qt_application import QtApplication app = QtApplication() window = ns[requested]() window.show() window.send_to_front() app.start() elif 'main' in ns: ns['main']() else: msg = "Could not find component '%s'" % options.component print(msg)
def _build_checker(self, check, set=False): """Assemble a checker function from the provided assertions. Parameters ---------- check : unicode ; separated string containing boolean test to assert. '{' and '}' delimit field which should be replaced by instrument state. 'value' should be considered a reserved keyword available when checking a set operation. Returns ------- checker : function Function to use """ func_def = 'def check(self, instance):\n' if not set\ else 'def check(self, instance, value):\n' assertions = check.split(';') for assertion in assertions: # First find replacement fields. aux = assertion.split('{') if len(aux) < 2: # Silently ignore checks unrelated to instrument state. continue line = 'assert ' els = [el.strip() for s in aux for el in s.split('}')] for i in range(0, len(els), 2): e = els[i] if i + 1 < len(els): line += e + ' getattr(instance, "{}") '.format(els[i + 1]) else: line += e values = ', '.join( ('getattr(instance, "{}")'.format(el) for el in els[1::2])) val_fmt = ', '.join(('{}'.format(el) + '={}' for el in els[1::2])) a_mess = 'assertion {} failed, '.format(' '.join(els).strip()) a_mess += 'values are : {}".format(self.name, {})'.format( val_fmt, values) if set: a_mess = '"Setting {} ' + a_mess else: a_mess = '"Getting {} ' + a_mess func_def += ' ' + line + ', ' + a_mess + '\n' loc = {} exec_(func_def, locs=loc) return loc['check']
def exec_code(self, filename, code, env): from future.utils import exec_ try: env['__name__'] = filename env['__loader__'] = ObjectDict(get_source=lambda name: code) c_code = compile(code, filename, 'exec', dont_inherit=True) exec_(c_code, env) return env except Exception as e: if self.global_options.verbose or self.options.error: type, value, tb = sys.exc_info() txt = ''.join(traceback.format_exception(type, value, tb)) print (txt) raise
def _test_pyfile(self, pyfile, want=True, comparator=None): with open(pyfile, 'rb') as fp: pycode = compile(fp.read(), pyfile, 'exec') result = exec_(pycode, globals(), locals()) # the exec:ed code is expected to set return_value got = locals()['return_value'] if not comparator: comparator = self.assertEqual comparator(want, got)
def refresh_view(self): """ Refresh the compiled view object. This method will (re)compile the view for the given view text and update the 'compiled_view' attribute. If a compiled model is available and the view has a member named 'model', the model will be applied to the view. """ text = self.view_text filename = self.view_filename _fake_linecache(text, filename) try: if not text: self.compiled_view = None self._view_module = None else: ast = parse(text, filename=filename) code = EnamlCompiler.compile(ast, filename) module = ModuleType('__main__') module.__file__ = filename namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) view = namespace.get(self.view_item, lambda: None)() if isinstance(view, Object) and 'model' in view.members(): view.model = self.compiled_model # trap any initialization errors and roll back the view old = self.compiled_view try: self.compiled_view = view except Exception: self.compiled_view = old if isinstance(old, Widget): old.show() raise self._view_module = module if old is not None and not old.is_destroyed: old.destroy() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def create_cache_func(func, **kwargs): kwargs = expand_memoize_args(kwargs) cache_obj = func.cache = MemoizeResults.caches[func] = create_cache_obj(**kwargs) stats_obj = func.stats = MemoizeResults.stats[func] = collections.Counter() definition = construct_cache_func_definition(**kwargs) namespace = { 'functools' : functools, 'release' : release, 'func' : func, 'stats' : stats_obj, 'cache' : cache_obj, 'zip' : zip, 'iteritems' : iteritems, 'lock' : threading.RLock(), 'gen_cache' : lambda: create_cache_obj(**kwargs), } exec_(definition, namespace) return namespace['memo_func']
def test_examples(enaml_qtbot, enaml_sleep, path, handler): """ Test the enaml examples. """ dir_path = os.path.abspath(os.path.split(os.path.dirname(__file__))[0]) enaml_file = os.path.join(dir_path, 'examples', os.path.normpath(path)) with open(enaml_file, 'rU') as f: enaml_code = f.read() # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning try: module = types.ModuleType('enaml_test') module.__file__ = os.path.abspath(enaml_file) sys.modules['enaml_test'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) with imports(): exec_(code, ns) window = ns['Main']() window.show() window.send_to_front() wait_for_window_displayed(enaml_qtbot, window) enaml_qtbot.wait(enaml_sleep * 1000) if handler is not None: handler(enaml_qtbot, window) finally: # Make sure we clean up the sys modification before leaving sys.path.pop(0) del sys.modules['enaml_test']
def execfile(filename, myglobals=None, mylocals=None): """ Read and execute a Python script from a file in the given namespaces. The globals and locals are dictionaries, defaulting to the current globals and locals. If only globals is given, locals defaults to it. """ if myglobals is None: # There seems to be no alternative to frame hacking here. caller_frame = inspect.stack()[1] myglobals = caller_frame[0].f_globals mylocals = caller_frame[0].f_locals elif mylocals is None: # Only if myglobals is given do we set mylocals to it. mylocals = myglobals if not isinstance(myglobals, Mapping): raise TypeError('globals must be a mapping') if not isinstance(mylocals, Mapping): raise TypeError('locals must be a mapping') with open(filename, "rbU") as fin: source = fin.read() code = compile(source, filename, "exec") exec_(code, myglobals, mylocals)
def create_cache_obj(**kwargs): kwargs = expand_memoize_args(kwargs) definition = construct_cache_obj_definition( kwargs['max_size'], kwargs['max_bytes'], kwargs['until'], kwargs['ignore_nulls'], kwargs['verbose'], ) namespace = { 'expire_func' : kwargs['until'], 'max_size' : kwargs['max_size'], 'max_bytes' : kwargs['max_bytes'], 'collections' : collections, 'sys' : sys, 'time' : time, } exec_(definition, namespace) return namespace['Cache']()
def _test_pyfile(self, pyfile, workingdir=None, want=True, comparator=None): if not workingdir: workingdir = os.getcwd() oldwd = os.getcwd() # we must read this in binary mode since the source code # contains encoding declarations pytext = util.readfile(pyfile, mode="rb") pycode = compile(pytext, pyfile, 'exec') os.chdir(workingdir) try: reload(ferenda) # so that ferenda.__file__ might return a abspath result = exec_(pycode, globals(), locals()) finally: os.chdir(oldwd) # the exec:ed code is expected to set return_value got = locals()['return_value'] if not comparator: comparator = self.assertEqual comparator(want, got)
def _GenerateFromEval(config, base, value_type): """@brief Evaluate a string as the provided type """ from future.utils import exec_ # These will be the variables to use for evaluating the eval statement. # Start with the current locals and globals, and add extra items to them. ldict = locals().copy() gdict = globals().copy() # We allow the following modules to be used in the eval string: exec_('import math', gdict) exec_('import numpy', gdict) exec_('import numpy as np', gdict) exec_('import os', gdict) #print('Start Eval') req = { 'str' : str } opt = {} ignore = galsim.config.standard_ignore # in value.py for key in config.keys(): if key not in (ignore + list(req)): opt[key] = _type_by_letter(key) #print('opt = ',opt) #print('base has ',base.keys()) #print('config = ',config) if isinstance(config['str'], str): # The ParseValue function can get confused if the first character is an @, but the # whole string isn't a Current item. e.g. @image.pixel_scale * @image.stamp_size. # So if config['str'] is a string, just get it. Otherwise, try parsing the dict. string = config['str'] params, safe = galsim.config.GetAllParams(config, base, opt=opt, ignore=ignore+['str']) else: params, safe = galsim.config.GetAllParams(config, base, req=req, opt=opt, ignore=ignore) #print('params = ',params) string = params['str'] #print('string = ',string) # Parse any "Current" items indicated with an @ sign. if '@' in string: import re # Find @items using regex. They can include alphanumeric chars plus '.'. keys = re.findall(r'@[\w\.]*', string) #print('@keys = ',keys) # Remove duplicates keys = np.unique(keys).tolist() #print('unique @keys = ',keys) for key0 in keys: key = key0[1:] # Remove the @ sign. value = galsim.config.GetCurrentValue(key, base) # Give a probably unique name to this value key_name = "temp_variable_" + key.replace('.','_') #print('key_name = ',key_name) #print('value = ',value) # Replaces all occurrences of key0 with the key_name. string = string.replace(key0,key_name) # Finally, bring the key's variable name into scope. ldict[key_name] = value # Bring the user-defined variables into scope. #print('Loading keys in ',opt) for key in opt: #print('key = ',key) ldict[key[1:]] = params[key] #print(key[1:],'=',eval(key[1:],gdict,ldict)) # Also bring in any top level eval_variables that might be relevant. if 'eval_variables' in base: #print('found eval_variables = ',base['eval_variables']) if not isinstance(base['eval_variables'],dict): raise AttributeError("eval_variables must be a dict") opt = {} ignore = [] for key in base['eval_variables']: # Only add variables that appear in the string. if key[1:] in string: opt[key] = _type_by_letter(key) else: ignore.append(key) #print('opt = ',opt) params, safe1 = galsim.config.GetAllParams(base['eval_variables'], base, opt=opt, ignore=ignore) #print('params = ',params) safe = safe and safe1 for key in opt: #print('key = ',key) ldict[key[1:]] = params[key] #print(key[1:],'=',eval(key[1:],gdict,ldict)) # Try evaluating the string as is. try: val = eval(string, gdict, ldict) if value_type is not None: val = value_type(val) #print(base['obj_num'],'Simple Eval(%s) = %s'%(string,val)) return val, safe except KeyboardInterrupt: raise except: pass # Then try bringing in the allowed variables to see if that works: base_variables = [ 'image_pos', 'world_pos', 'image_center', 'image_origin', 'image_bounds', 'image_xsize', 'image_ysize', 'stamp_xsize', 'stamp_ysize', 'pixel_scale', 'wcs', 'rng', 'file_num', 'image_num', 'obj_num', 'start_obj_num', ] for key in base_variables: if key in base: ldict[key] = base[key] try: val = eval(string, gdict, ldict) #print(base['obj_num'],'Eval(%s) needed extra variables: val = %s'%(string,val)) if value_type is not None: val = value_type(val) return val, False except KeyboardInterrupt: raise except Exception as e: raise ValueError("Unable to evaluate string %r as a %s\n"%(string,value_type) + str(e))
def BuildGSObject(config, key, base=None, gsparams={}, logger=None): """Build a GSObject from the parameters in config[key]. Parameters: config: A dict with the configuration information. key: The key name in config indicating which object to build. base: The base dict of the configuration. [default: config] gsparams: Optionally, provide non-default GSParams items. Any ``gsparams`` specified at this level will be added to the list. This should be a dict with whatever kwargs should be used in constructing the GSParams object. [default: {}] logger: Optionally, provide a logger for logging debug statements. [default: None] Returns: the tuple (gsobject, safe), where ``gsobject`` is the built object, and ``safe`` is a bool that says whether it is safe to use this object again next time. """ from .. import __dict__ as galsim_dict logger = LoggerWrapper(logger) if base is None: base = config logger.debug('obj %d: Start BuildGSObject %s', base.get('obj_num', 0), key) # If key isn't in config, then just return None. try: param = config[key] except KeyError: return None, True # Check what index key we want to use for this object. # Note: this call will also set base['index_key'] and base['rng'] to the right values index, index_key = GetIndex(param, base) # Get the type to be parsed. if not 'type' in param: raise GalSimConfigError("type attribute required in config.%s" % key) type_name = param['type'] # If we are repeating, then we get to use the current object for repeat times. if 'repeat' in param: repeat = ParseValue(param, 'repeat', base, int)[0] else: repeat = 1 # Check if we need to skip this object if 'skip' in param: skip = ParseValue(param, 'skip', base, bool)[0] if skip: logger.debug('obj %d: Skipping because field skip=True', base.get('obj_num', 0)) raise SkipThisObject() # Check if we can use the current cached object if 'current' in param: # NB. "current" tuple is (obj, safe, None, index, index_type) cobj, csafe, cvalue_type, cindex, cindex_type = param['current'] if csafe or cindex // repeat == index // repeat: # If logging, explain why we are using the current object. if logger: if csafe: logger.debug('obj %d: current is safe', base.get('obj_num', 0)) elif repeat > 1: logger.debug( 'obj %d: repeat = %d, index = %d, use current object', base.get('obj_num', 0), repeat, index) else: logger.debug('obj %d: This object is already current', base.get('obj_num', 0)) return cobj, csafe # Set up the initial default list of attributes to ignore while building the object: ignore = [ 'dilate', 'dilation', 'ellip', 'rotate', 'rotation', 'scale_flux', 'magnify', 'magnification', 'shear', 'shift', 'gsparams', 'skip', 'current', 'index_key', 'repeat' ] # There are a few more that are specific to which key we have. if key == 'gal': ignore += ['resolution', 'signal_to_noise', 'redshift', 're_from_res'] elif key == 'psf': ignore += ['saved_re'] else: # As long as key isn't psf, allow resolution. # Ideally, we'd like to check that it's something within the gal hierarchy, but # I don't know an easy way to do that. ignore += ['resolution', 're_from_res'] # Allow signal_to_noise for PSFs only if there is not also a galaxy. if 'gal' not in base and key == 'psf': ignore += ['signal_to_noise'] # If we are specifying the size according to a resolution, then we # need to get the PSF's half_light_radius. if 'resolution' in param: if 'psf' not in base: raise GalSimConfigError( "Cannot use gal.resolution if no psf is set.") if 'saved_re' not in base['psf']: raise GalSimConfigError( 'Cannot use gal.resolution with psf.type = %s' % base['psf']['type']) psf_re = base['psf']['saved_re'] resolution = ParseValue(param, 'resolution', base, float)[0] gal_re = resolution * psf_re if 're_from_res' not in param: # The first time, check that half_light_radius isn't also specified. if 'half_light_radius' in param: raise GalSimConfigError( 'Cannot specify both gal.resolution and gal.half_light_radius' ) param['re_from_res'] = True param['half_light_radius'] = gal_re # Make sure the PSF gets flux=1 unless explicitly overridden by the user. if key == 'psf' and 'flux' not in param and 'signal_to_noise' not in param: param['flux'] = 1 if 'gsparams' in param: gsparams = UpdateGSParams(gsparams, param['gsparams'], base) # See if this type is registered as a valid type. if type_name in valid_gsobject_types: build_func = valid_gsobject_types[type_name] elif type_name in galsim_dict: from future.utils import exec_ gdict = globals().copy() exec_('import galsim', gdict) build_func = eval("galsim." + type_name, gdict) else: raise GalSimConfigValueError("Unrecognised gsobject type", type_name) if inspect.isclass(build_func) and issubclass(build_func, GSObject): gsobject, safe = _BuildSimple(build_func, param, base, ignore, gsparams, logger) else: gsobject, safe = build_func(param, base, ignore, gsparams, logger) # If this is a psf, try to save the half_light_radius in case gal uses resolution. if key == 'psf': try: param['saved_re'] = gsobject.half_light_radius except (AttributeError, NotImplementedError, TypeError): pass # Apply any dilation, ellip, shear, etc. modifications. gsobject, safe1 = TransformObject(gsobject, param, base, logger) safe = safe and safe1 param['current'] = gsobject, safe, None, index, index_key return gsobject, safe
def _GenerateFromEval(config, base, value_type): """Evaluate a string as the provided type """ #print('Start Eval') #print('config = ',galsim.config.CleanConfig(config)) if '_value' in config: return config['_value'] elif '_fn' in config: #print('Using saved function') fn = config['_fn'] else: # If the function is not already compiled, then this is the first time through, so do # a full parsing of all the possibilities. from future.utils import exec_ # These will be the variables to use for evaluating the eval statement. # Start with the current locals and globals, and add extra items to them. if 'eval_gdict' not in base: gdict = globals().copy() # We allow the following modules to be used in the eval string: exec_('import math', gdict) exec_('import numpy', gdict) exec_('import numpy as np', gdict) exec_('import os', gdict) base['eval_gdict'] = gdict else: gdict = base['eval_gdict'] if 'str' not in config: raise galsim.GalSimConfigError( "Attribute str is required for type = %s" % (config['type'])) string = config['str'] # Turn any "Current" items indicated with an @ sign into regular variables. if '@' in string: # Find @items using regex. They can include alphanumeric chars plus '.'. keys = re.findall(r'@[\w\.]*', string) #print('@keys = ',keys) # Remove duplicates keys = np.unique(keys).tolist() #print('unique @keys = ',keys) for key0 in keys: key = key0[1:] # Remove the @ sign. value = galsim.config.GetCurrentValue(key, base) # Give a probably unique name to this value key_name = "temp_variable_" + key.replace('.', '_') #print('key_name = ',key_name) #print('value = ',value) # Replaces all occurrences of key0 with the key_name. string = string.replace(key0, key_name) # Finally, bring the key's variable name into scope. config['x' + key_name] = {'type': 'Current', 'key': key} # The parameters to the function are the keys in the config dict minus their initial char. params = [key[1:] for key in config.keys() if key not in eval_ignore] # Also bring in any top level eval_variables that might be relevant. if 'eval_variables' in base: #print('found eval_variables = ',galsim.config.CleanConfig(base['eval_variables'])) if not isinstance(base['eval_variables'], dict): raise galsim.GalSimConfigError("eval_variables must be a dict") for key in base['eval_variables']: # Only add variables that appear in the string. if _isWordInString(key[1:], string) and key[1:] not in params: config[key] = { 'type': 'Current', 'key': 'eval_variables.' + key } params.append(key[1:]) # Also check for the allowed base variables: for key in eval_base_variables: if key in base and _isWordInString(key, string) and key not in params: config['x' + key] = {'type': 'Current', 'key': key} params.append(key) #print('params = ',params) #print('config = ',config) # Now compile the string into a lambda function, which will be faster for subsequent # passes into this builder. try: if len(params) == 0: value = eval(string, gdict) config['_value'] = value return value else: fn_str = 'lambda %s: %s' % (','.join(params), string) #print('fn_str = ',fn_str) fn = eval(fn_str, gdict) config['_fn'] = fn except KeyboardInterrupt: raise except Exception as e: raise galsim.GalSimConfigError( "Unable to evaluate string %r as a %s\n%r" % (string, value_type, e)) # Always need to evaluate any parameters to pass to the function opt = {} for key in config.keys(): if key not in eval_ignore: opt[key] = _type_by_letter(key) #print('opt = ',opt) params, safe = galsim.config.GetAllParams(config, base, opt=opt, ignore=eval_ignore) #print('params = ',params) # Strip off the first character of the keys params = {key[1:]: value for key, value in params.items()} #print('params => ',params) # Evaluate the compiled function try: val = fn(**params) #print('val = ',val) return val, safe except KeyboardInterrupt: raise except Exception as e: raise galsim.GalSimConfigError( "Unable to evaluate string %r as a %s\n%r" % (config['str'], value_type, e))
def _GenerateFromEval(config, base, value_type): """@brief Evaluate a string as the provided type """ #print('Start Eval') #print('config = ',galsim.config.CleanConfig(config)) if '_value' in config: return config['_value'] elif '_fn' in config: #print('Using saved function') fn = config['_fn'] else: # If the function is not already compiled, then this is the first time through, so do # a full parsing of all the possibilities. from future.utils import exec_ # These will be the variables to use for evaluating the eval statement. # Start with the current locals and globals, and add extra items to them. if 'eval_gdict' not in base: gdict = globals().copy() # We allow the following modules to be used in the eval string: exec_('import math', gdict) exec_('import numpy', gdict) exec_('import numpy as np', gdict) exec_('import os', gdict) base['eval_gdict'] = gdict else: gdict = base['eval_gdict'] if 'str' not in config: raise galsim.GalSimConfigError( "Attribute str is required for type = %s"%(config['type'])) string = config['str'] # Turn any "Current" items indicated with an @ sign into regular variables. if '@' in string: # Find @items using regex. They can include alphanumeric chars plus '.'. keys = re.findall(r'@[\w\.]*', string) #print('@keys = ',keys) # Remove duplicates keys = np.unique(keys).tolist() #print('unique @keys = ',keys) for key0 in keys: key = key0[1:] # Remove the @ sign. value = galsim.config.GetCurrentValue(key, base) # Give a probably unique name to this value key_name = "temp_variable_" + key.replace('.','_') #print('key_name = ',key_name) #print('value = ',value) # Replaces all occurrences of key0 with the key_name. string = string.replace(key0,key_name) # Finally, bring the key's variable name into scope. config['x' + key_name] = { 'type' : 'Current', 'key' : key } # The parameters to the function are the keys in the config dict minus their initial char. params = [ key[1:] for key in config.keys() if key not in eval_ignore ] # Also bring in any top level eval_variables that might be relevant. if 'eval_variables' in base: #print('found eval_variables = ',galsim.config.CleanConfig(base['eval_variables'])) if not isinstance(base['eval_variables'],dict): raise galsim.GalSimConfigError("eval_variables must be a dict") for key in base['eval_variables']: # Only add variables that appear in the string. if _isWordInString(key[1:],string) and key[1:] not in params: config[key] = { 'type' : 'Current', 'key' : 'eval_variables.' + key } params.append(key[1:]) # Also check for the allowed base variables: for key in eval_base_variables: if key in base and _isWordInString(key,string) and key not in params: config['x' + key] = { 'type' : 'Current', 'key' : key } params.append(key) #print('params = ',params) #print('config = ',config) # Now compile the string into a lambda function, which will be faster for subsequent # passes into this builder. try: if len(params) == 0: value = eval(string, gdict) config['_value'] = value return value else: fn_str = 'lambda %s: %s'%(','.join(params), string) #print('fn_str = ',fn_str) fn = eval(fn_str, gdict) config['_fn'] = fn except KeyboardInterrupt: raise except Exception as e: raise galsim.GalSimConfigError( "Unable to evaluate string %r as a %s\n%r"%(string, value_type, e)) # Always need to evaluate any parameters to pass to the function opt = {} for key in config.keys(): if key not in eval_ignore: opt[key] = _type_by_letter(key) #print('opt = ',opt) params, safe = galsim.config.GetAllParams(config, base, opt=opt, ignore=eval_ignore) #print('params = ',params) # Strip off the first character of the keys params = { key[1:] : value for key, value in params.items() } #print('params => ',params) # Evaluate the compiled function try: val = fn(**params) #print('val = ',val) return val, safe except KeyboardInterrupt: raise except Exception as e: raise galsim.GalSimConfigError( "Unable to evaluate string %r as a %s\n%r"%(config['str'],value_type, e))
__author__ = 'chad nelson' __project__ = 'blowdrycss' # Get readme.rst from sphinx docs. try: with open('readme.rst', encoding='utf-8') as f: long_description = f.read() except (IOError, ImportError): # default description long_description = 'Rapid styling tool used to auto-generate DRY CSS files from encoded class selectors.' # Get current version number. # http://python-future.org/_modules/future/utils.html#exec_ version = {} with open('version.py') as _file: exec_(_file.read(), version) setup( name='blowdrycss', # Versions should comply with PEP440. For a discussion on single-sourcing # the version across setup.py and the project code, see # https://packaging.python.org/en/latest/single_source_version.html version=version['__version__'], description='The atomic CSS compiler', long_description=long_description, # The project's main homepage. url='http://blowdrycss.org', download_url='https://github.com/nueverest/blowdrycss/archive/master.zip',