Example #1
0
def given_namespace_is_used(context, namespace_name):
    namespace = Namespace(namespace_name)
    if not namespace.is_present():
        print("Namespace is not present, creating namespace: {}...".format(namespace_name))
        namespace.create() | should.be_truthy.desc("Namespace {} is created".format(namespace_name))
    print("Namespace {} is created!!!".format(namespace_name))
    context.namespace = namespace
Example #2
0
 def __init__(self,
              base_dir=None,
              name='simplecli'):
     self.name = name
     self.logger = Logger(name=name, level=INFO)
     handler = StreamHandler(sys.stdout)
     handler.setLevel(DEBUG)
     handler.setFormatter(Formatter(
         magenta('[%(asctime)s]%(message)s')))
     self.logger.addHandler(handler)
     self._config_namespaces = Namespace()
     self.menu_cache = []
     self.completer_context = None
     self.base_dir = base_dir or os.path.expanduser('~/.simplecli')
     if os.path.exists(self.base_dir):
         if not os.path.isdir(self.base_dir):
             raise ValueError('base dir provided is not a dir:"{0}'
                              .format(self.base_dir))
     else:
         os.makedirs(self.base_dir)
     self.simplecli_config_file = os.path.join(self.base_dir,
                                               str(name) + '.config')
     self.simplecli_config = None
     self.init_simplecli_config()
     self._setup_stdio()
     self._load_plugin_menus()
Example #3
0
 def __init__(self):
     """
     Construct a new SallyForth execution environment.
     """
     self.stack = Stack()
     self.stream = None
     core = Namespace('core')
     user = Namespace('user', [core])
     user.include_ns(core)
     self.namespaces = {}
     self.namespaces[core.name] = core
     self.namespaces[user.name] = user
     self.ns = core
     self.core = core
     self.set_constant('forth', self)
     self.set_constant('nil', None)
     self.set_constant('true', True)
     self.set_constant('false', False)
     self.set_constant('*source*', '<<input>>')
     self.set_constant('*last-word*', None)
     sally_dir = os.path.dirname(os.path.abspath(__file__))
     self.set_constant('*sallyforth-dir*', sally_dir)
     self.ns.import_from_module('basic_words')
     self.ns.import_from_module('namespace_words')
     self.ns.import_from_module('stack_words')
     self.ns.import_from_module('operator_words')
     self.ns.import_from_module('data_words')
     self.eval_file(f'{sally_dir}/0.sf')
     self.ns = user
Example #4
0
 def test_info_without_install(self):
     with pytest.raises(
             StateCheckError,
             message=
             'Executing info action without install should raise an error'):
         ns = Namespace(name='namespace', data=self.valid_data)
         ns.info()
Example #5
0
    def testGetWithFlags(self):
        '''
        Test get with flags
        '''
        ns = Namespace()
        ns._DeclareFlag('win32', 'Windows-OS')

        ns['lib_dir'] = 'lib'
        ns['win32:lib_dir'] = 'lib/win32'
        assert ns.GetValue('lib_dir', as_string=True) == 'lib'
        assert ns.GetValue('win32:lib_dir', as_string=True) == 'lib/win32'

        ns['win32:lib_dir'] = 'library/windows'
        assert ns.GetValue('lib_dir', as_string=True) == 'lib'
        assert ns.GetValue('win32:lib_dir', as_string=True) == 'library/windows'

        ns['win32:lib_dir'] = 'lib-w32'
        assert ns.GetValue('lib_dir', as_string=True) == 'lib'
        assert ns.GetValue('win32:lib_dir', as_string=True) == 'lib-w32'

        # Indirect flagged value
        ns['win32:lib_dir'] = 'lib-w32'
        ns['lib_dir2'] = 'LIB `lib_dir`'

        assert ns.GetValue('lib_dir2', as_string=True) == 'LIB lib'
        assert ns.GetValue('win32:lib_dir2', as_string=True) == 'LIB lib-w32'
Example #6
0
def given_namespace_is_used(context, namespace_name):
    namespace = Namespace(namespace_name)
    if not namespace.is_present():
        print("Namespace is not present, creating namespace: {}...".format(namespace_name))
        assert namespace.create(), f"Unable to create namespace '{namespace_name}'"
    print("Namespace {} is created!!!".format(namespace_name))
    context.namespace = namespace
Example #7
0
 def _setup_admin_options(self, values_source_list):
     base_namespace = Namespace()
     base_namespace.admin = admin = Namespace()
     admin.add_option(
         name='print_conf',
         default=None,
         doc='write current config to stdout (%s)' %
         ', '.join(value_sources.file_extension_dispatch.keys()))
     admin.add_option(
         name='dump_conf',
         default='',
         doc='a pathname to which to write the current config',
     )
     admin.add_option(name='migration',
                      default=False,
                      doc='allow common options to migrate to lower '
                      'levels')
     admin.add_option(name='strict',
                      default=False,
                      doc='mismatched options generate exceptions rather'
                      ' than just warnings')
     # only offer the config file admin options if they've been requested in
     # the values source list
     if ConfigFileFutureProxy in values_source_list:
         default_config_pathname = self._get_config_pathname()
         admin.add_option(
             name='conf',
             default=default_config_pathname,
             doc='the pathname of the config file '
             '(path/filename)',
         )
     return base_namespace
Example #8
0
 def test_valid_data(self):
     ns = Namespace(name='namespace', data=self.valid_data)
     ns.api.services.get = MagicMock()
     ns.validate()
     data = self.valid_data.copy()
     data['zerodb'] = ''
     data['nsName'] = ''
     assert ns.data == data
Example #9
0
def test(cfg: Namespace) -> None:
    assert cfg.checkpoint not in [None, ""]
    assert cfg.device == "cpu" or (cfg.device == "cuda"
                                   and T.cuda.is_available())

    exp_dir = ROOT_EXP_DIR / cfg.exp_name
    os.makedirs(exp_dir / "out", exist_ok=True)
    cfg.to_file(exp_dir / "test_config.json")
    logger.info(f"[exp dir={exp_dir}]")

    model = CAE()
    model.load_state_dict(T.load(cfg.checkpoint))
    model.eval()
    if cfg.device == "cuda":
        model.cuda()
    logger.info(f"[model={cfg.checkpoint}] on {cfg.device}")

    dataloader = DataLoader(dataset=ImageFolder720p(cfg.dataset_path),
                            batch_size=1,
                            shuffle=cfg.shuffle)
    logger.info(f"[dataset={cfg.dataset_path}]")

    loss_criterion = nn.MSELoss()

    for batch_idx, data in enumerate(dataloader, start=1):
        img, patches, _ = data
        if cfg.device == "cuda":
            patches = patches.cuda()

        if batch_idx % cfg.batch_every == 0:
            pass

        out = T.zeros(6, 10, 3, 128, 128)
        avg_loss = 0

        for i in range(6):
            for j in range(10):
                x = patches[:, :, i, j, :, :].cuda()
                y = model(x)
                out[i, j] = y.data

                loss = loss_criterion(y, x)
                avg_loss += (1 / 60) * loss.item()

        logger.debug("[%5d/%5d] avg_loss: %f", batch_idx, len(dataloader),
                     avg_loss)

        # save output
        out = np.transpose(out, (0, 3, 1, 4, 2))
        out = np.reshape(out, (768, 1280, 3))
        out = np.transpose(out, (2, 0, 1))

        y = T.cat((img[0], out), dim=2)
        save_imgs(
            imgs=y.unsqueeze(0),
            to_size=(3, 768, 2 * 1280),
            name=exp_dir / f"out/test_{batch_idx}.png",
        )
Example #10
0
    def __init__(self, name=None, type=None, arguments=None, body=None):
        Namespace.__init__(self)

        self.parent_namespace = None

        self.name = name
        self.type = type
        self.arguments = arguments if arguments else []
        self.body = body
Example #11
0
def namespace_maybe_create(context, namespace_name):
    namespace = Namespace(namespace_name)
    if not namespace.is_present():
        print("Namespace is not present, creating namespace: {}...".format(
            namespace_name))
        assert namespace.create(
        ), f"Unable to create namespace '{namespace_name}'"
    print("Namespace {} is created!!!".format(namespace_name))
    return namespace
Example #12
0
    def testVariableNotFound(self):
        ns = Namespace()
        with pytest.raises(NamespaceKeyError):
            ns.GetValue('alpha')

        ns._DeclareFlag('win32', 'Platform flag for all Windows systems.')
        ns['win32:alpha'] = 'Alpha'

        with pytest.raises(NamespaceKeyError):
            ns.GetValue('alpha')
Example #13
0
 def test_connection_info(self):
     ns = Namespace(name='namespace', data=self.valid_data)
     ns.state.set('actions', 'install', 'ok')
     ns.state.set('status', 'running', 'ok')
     ns.api = MagicMock()
     result = {'ip': '127.0.0.1', 'port': 9900}
     task = task_mock(result)
     ns._zerodb.schedule_action = MagicMock(return_value=task)
     assert ns.connection_info() == result
     ns._zerodb.schedule_action.assert_called_once_with('connection_info')
Example #14
0
    def test_private_url(self):
        ns = Namespace(name='namespace', data=self.valid_data)
        ns.data['nsName'] = 'nsName'
        ns.state.set('actions', 'install', 'ok')
        ns.api = MagicMock()
        ns._zerodb.schedule_action = MagicMock(return_value=task_mock('url'))

        assert ns.private_url() == 'url'
        ns._zerodb.schedule_action.assert_called_once_with(
            'namespace_private_url', args={'name': 'nsName'})
Example #15
0
    def testFlagsDeclaration(self):
        '''
        Test the declaration of flags and the error raised when trying to declare a variable
        using an undeclared flag.
        '''
        ns = Namespace()
        ns['name'] = 'alpha-flagless'

        # Declare the flag and then declare the name using it.
        ns._DeclareFlag('win32', 'Platform flag for all Windows systems.')
        ns['win32:name'] = 'alpha-w32'
Example #16
0
    def test_info(self):
        ns = Namespace(name='namespace', data=self.valid_data)
        ns.data['nsName'] = 'nsName'
        ns.state.set('actions', 'install', 'ok')
        ns.api = MagicMock()
        task = task_mock('info')
        ns._zerodb.schedule_action = MagicMock(return_value=task)

        assert ns.info() == 'info'
        ns._zerodb.schedule_action.assert_called_once_with(
            'namespace_info', args={'name': ns.data['nsName']})
def given_knative_serving_is_running(context):
    """
    creates a KnativeServing object to install Knative Serving using the OpenShift Serverless Operator.
    """
    knative_namespace = Namespace("knative-serving")
    assert knative_namespace.create() is True, "Knative serving namespace not created"
    knative_serving = KnativeServing(namespace=knative_namespace.name)
    if not knative_serving.is_present():
        print("knative serving is not present, create knative serving")
        assert knative_serving.create() is True, "Knative serving is not created"
        assert knative_serving.is_present() is True, "Knative serving is not present"
Example #18
0
 def test_invalid_data(self):
     with pytest.raises(
             ValueError,
             message=
             'template should fail to instantiate if data dict is missing the size'
     ):
         data = self.valid_data.copy()
         data.pop('size')
         ns = Namespace(name='namespace', data=data)
         ns.api.services.get = MagicMock()
         ns.validate()
Example #19
0
	def __update_markup_block(self, source, block_name, tiddler_name):
		# tiddler in this tiddlywiki
		tiddler = Namespace.get_tiddler(self.name+"::"+tiddler_name, self.owner.username, self.namespace.name)
		if not tiddler:
			# tiddler in Namespace
			tiddler = Namespace.get_tiddler(tiddler_name, self.owner.username, self.namespace.name)
		if not tiddler:
			# tiddler in Shadow
			tiddler = Namespace.get_tiddler(tiddler_name)
		if tiddler:
			source = self.__replace_chunk(
				source,
				"<!--%s-START-->"%block_name,
				"<!--%s-END-->"%block_name,
				"\n" + tiddler.text + "\n")
		return source		
Example #20
0
class GroundOverlay(KMLObject):
    defaults = Namespace(
        name='',
        drawOrder=1,
        href='',
        viewBoundScale=0.75,
        north=None,
        east=None,
        west=None,
        south=None,
        rotation=0,
        data=Data(),
        description='',
        colour='ffffffff',
    )

    def __init__(self, north, east, south, west, href, **kwargs):
        self.args = GroundOverlay.defaults
        self.args.update(north=north,
                         east=east,
                         south=south,
                         west=west,
                         href=href,
                         **kwargs)

    def add_data(self, data):
        self.args.data.append(data)

    def write(self):
        self.args.update(data=self.args.data.write())
        return Formats.GroundOverlay.format(**self.args.asdict())
Example #21
0
class ScreenOverlay(KMLObject):
    defaults = Namespace(
        name='',
        description='',
        href='',
        xOverlay=0,
        yOverlay=1,
        xunitsOverlay='fraction',
        yunitsOverlay='fraction',
        xScreen=0.01,
        yScreen=0.99,
        xunitsScreen='fraction',
        yunitsScreen='fraction',
        xsize=0.5,
        ysize=0.1,
        xunits='fraction',
        yunits='fraction',
        xRotation=0.5,
        yRotation=0.5,
        xunitsRotation='fraction',
        yunitsRotation='fraction',
        rotation=0,
    )

    def __init__(self, href, **kwargs):
        self.args = ScreenOverlay.defaults
        self.args.update(href=href, **kwargs)

    def write(self):
        return Formats.ScreenOverlay.format(**self.args.asdict())
Example #22
0
class Placemark(KMLObject):
    yellow_pushpin = IconStyle('yellow-pushpin')
    defaults = Namespace(
        name='Placemark',
        lon='',
        lat='',
        altitude=0,
        heading=0,
        tilt=0,
        range=0,
        styleUrl='',
        LookAt=None,
    )

    def __init__(self, name, lat, lon, style=yellow_pushpin, **kwargs):
        self.args = Placemark.defaults
        self.args.update(name=name, lat=lat, lon=lon, **kwargs)
        self.args.update(styleUrl=style.tag)

        if not self.args.LookAt:
            lookat = LookAt(self.args.lat, self.args.lon)
            self.args.LookAt = lookat

    def write(self):
        self.args.update
        self.args.update(LookAt=self.args.LookAt.write())
        placemark = Formats.placemark.format(**self.args.asdict())
        return placemark
Example #23
0
    def __init__(self, factory, fuzz_spec):
        assert factory, 'Factory not set.'
        self._factory = factory
        self._label = fuzz_spec['label']
        self._package = fuzz_spec['package']
        self._package_url = fuzz_spec['package_url']
        self._package_path = None
        if 'fuzzer' in fuzz_spec:
            self._executable = fuzz_spec['fuzzer']
            manifest = fuzz_spec['manifest']
            self._is_test = False
        elif 'fuzzer_test' in fuzz_spec:
            # Infer the associated fuzzer metadata if it is currently being built as a fuzzer test.
            self._executable = re.sub(r'_test$', '', fuzz_spec['fuzzer_test'])
            manifest = re.sub(r'_test\.cmx$', '.cmx',
                              fuzz_spec['test_manifest'])
            self._is_test = True

        self._executable_url = '{}#meta/{}'.format(self._package_url, manifest)
        self._ns = Namespace(self)
        self._corpus = Corpus(self, fuzz_spec.get('corpus'))
        self._dictionary = Dictionary(self)
        self._options = {'artifact_prefix': self.ns.data()}
        self._libfuzzer_opts = {}
        self._libfuzzer_inputs = []
        self._subprocess_args = []
        self._debug = False
        self._foreground = False
        self._output = None
        self._logbase = None
        self._last_known_pid = 0
        self._clusterfuzz_gcs_url = \
            'gs://corpus.internal.clusterfuzz.com/libFuzzer/fuchsia_{}-{}'.format(
                self._package, self._executable)
        self._realm_label = ''
Example #24
0
 def __update_markup_block(self, source, block_name, tiddler_name):
     # tiddler in this tiddlywiki
     tiddler = Namespace.get_tiddler(self.name + "::" + tiddler_name,
                                     self.owner.username,
                                     self.namespace.name)
     if not tiddler:
         # tiddler in Namespace
         tiddler = Namespace.get_tiddler(tiddler_name, self.owner.username,
                                         self.namespace.name)
     if not tiddler:
         # tiddler in Shadow
         tiddler = Namespace.get_tiddler(tiddler_name)
     if tiddler:
         source = self.__replace_chunk(source,
                                       "<!--%s-START-->" % block_name,
                                       "<!--%s-END-->" % block_name,
                                       "\n" + tiddler.text + "\n")
     return source
Example #25
0
def merge_overrides(args: argparse.Namespace, config: ns.Namespace):
    """Merge command line overrides into configuration"""

    config.no_gui = args.no_gui
    for arg in ARGS:
        value = getattr(args, cast(str, arg['name']))
        if not value:
            continue
        ns.set_in_path(config, cast(str, arg['path']), value)
class IndustrialAge(Era):
    __metaclass__ = Namespace(ColonialAge)

    class GameUnit:
        def move(self):
            return "IndustrialAge.GameUnit.move()"

    class RangedUnit:
        def aim(self):
            return "IndustrialAge.RangedUnit.aim()"
Example #27
0
    def testPrint(self):
        ns = Namespace(flags=['win32'])
        ns._DeclareFlag('win32', 'Windows-OS')
        ns._DeclareFlag('mac', 'Mac-OS')
        ns['alpha'] = 'Alpha'
        ns['win32:alpha'] = 'Alpha-W32'
        ns['mac:alpha'] = 'Alpha-MAC'

        oss = StringIO()
        ns.Print(oss)

        assert (
            oss.getvalue()
            == '\n'
            '  alpha = STRING:Alpha\n'
            '        = (mac) STRING:Alpha-MAC\n'
            '        = (win32) STRING:Alpha-W32\n'
        )

        oss = StringIO()
        ns.Print(oss, evaluate=True)
        assert (
            oss.getvalue()
            == '\n'
            '  alpha = Alpha-W32\n'
        )

        oss = StringIO()
        ns.PrintDeclaredFlags(oss)
        assert (
            oss.getvalue()
            == '\n'
            '  mac = Mac-OS\n'
            '  win32 = Windows-OS\n',
        )

        oss = StringIO()
        ns.PrintImplicitFlags(oss)
        assert (
            oss.getvalue()
            == '\n'
            '  win32\n',
        )
Example #28
0
    def __init__(self, world_id, world_init_prop):
        self.name = Namespace(namespace='world/', name=world_id)
        self.__init_properties = world_init_prop

        self.launch = None
        self.__init_launch()

        self.__env = Environment(owner=self, properties=self.__init_properties)

        self.__env.launch()
Example #29
0
        class InnerClassList(RequiredConfig):
            """This nested class is a proxy list for the classes.  It collects
            all the config requirements for the listed classes and places them
            each into their own Namespace.
            """
            # we're dynamically creating a class here.  The following block of
            # code is actually adding class level attributes to this new class
            required_config = Namespace()  # 1st requirement for configman
            subordinate_namespace_names = []  # to help the programmer know
            # what Namespaces we added
            namespace_template = template_for_namespace  # save the template
            # for future reference
            class_option_name = name_of_class_option  # save the class's option
            # name for the future
            # for each class in the class list
            for namespace_index, a_class in enumerate(class_list):
                # figure out the Namespace name
                namespace_name = template_for_namespace % namespace_index
                subordinate_namespace_names.append(namespace_name)
                # create the new Namespace
                required_config[namespace_name] = Namespace()
                # add the option for the class itself
                required_config[namespace_name].add_option(
                    name_of_class_option,
                    #doc=a_class.__doc__  # not helpful if too verbose
                    default=a_class,
                    from_string_converter=class_converter)
                if instantiate_classes:
                    # add an aggregator to instantiate the class
                    required_config[namespace_name].add_aggregation(
                        "%s_instance" % name_of_class_option,
                        lambda c, lc, a: lc[name_of_class_option](lc))

            @classmethod
            def to_str(cls):
                """this method takes this inner class object and turns it back
                into the original string of classnames.  This is used
                primarily as for the output of the 'help' option"""
                return ', '.join(
                    py_obj_to_str(v[name_of_class_option].value)
                    for v in cls.get_required_config().values()
                    if isinstance(v, Namespace))
Example #30
0
 def __call__(self, *arg_vals):
     num_args = len(arg_vals)
     if num_args == self.arity:
         obj_dict = dict(zip(self.args, arg_vals))
         local_scope = Namespace(parent=self.scope, obj_dict=obj_dict)
         for statement in self.statements:
             statement.exec(local_scope)
     else:
         raise TypeError(
             "attempted to pass {0} arguments to function {1} of arity {2}".
             format(num_args, self.name, self.arity))
Example #31
0
	def interactive_mode():
		try:
			action_list = ("add", "rename", "delete", "enable", "disable", "search", "clear", "trigger")
			Utils.debug_print("SuperCron (interactive mode)")
			Utils.debug_print("")
			action = raw_input("Action [add/rename/delete/enable/disable/trigger/search/clear]: ")
			action = str(action.lower().strip())
			if action not in action_list:
				Utils.debug_print("Error: action '{}' not recognized.".format(action))
				sys.exit(1)
			args = Namespace()
			if action == "clear":
				Utils.debug_print("")
				SuperCron.clear_jobs(args)
				return
			if action == "rename":
				args.old_name = raw_input("Job old name: ")
				args.new_name = raw_input("Job new name: ")
				Utils.debug_print("")
				SuperCron.rename_job(args)
				return
			if action == "trigger":
				trigger_parts = []
				args.name = raw_input("Enter name of triggered job: ")
				trigger_parts.append(raw_input("Action on the triggered job [on/off/toggle]: "))
				trigger_parts.append(raw_input("Name of the triggering job: "))
				trigger_parts.append(raw_input("Condition on the triggering job [enabled/disabled/toggled/added/deleted]: "))
				args.trigger = ["{t[0]} if {t[1]} is {t[2]}".format(t=trigger_parts)]
				Utils.debug_print("")
				SuperCron.trigger_job(args)
				return
			args.name = raw_input("Job name: ")
			if action == "add":
				args.command = [raw_input("Command to be executed: ")]
				args.repetition = [raw_input("Repetition sentence: ")]
				Utils.debug_print("")
				SuperCron.add_job(args)
			elif action == "delete":
				Utils.debug_print("")
				SuperCron.delete_job(args)
			elif action == "enable":
				Utils.debug_print("")
				SuperCron.enable_job(args)
			elif action == "disable":
				Utils.debug_print("")
				SuperCron.disable_job(args)
			elif action == "search":
				Utils.debug_print("")
				SuperCron.search_job(args)
		except KeyboardInterrupt:
			Utils.debug_print("\nCancelled.")
Example #32
0
    def testEvaluateFlags(self):
        ns = Namespace(flags=['win32', 'other_flag'])
        ns._DeclareFlag('other_flag', 'Flag for testing')
        ns._DeclareFlag('win32', 'Windows-OS')
        ns._DeclareFlag('linux', 'Linux-OS')

        assert ns.EvaluateFlags('')
        assert ns.EvaluateFlags('win32')
        assert ns.EvaluateFlags('win32:other_flag')
        assert not ns.EvaluateFlags('!win32')
Example #33
0
class PolyStyle(KMLObject):
    defaults = Namespace(fillcolour='ffa9a9a9',
                         linecolour='ffa9a9a9',
                         linewidth=1,
                         style='')

    def __init__(self, id, **kwargs):
        self.args = PolyStyle.defaults
        self.args.update(style=id, **kwargs)
        self.tag = Formats.StyleUrl.format(url=id)

    def write(self):
        return Formats.PolyStyle.format(**self.args.asdict())
Example #34
0
 def add_namespace(self, name):
     '''
     Adds a blank configuration namespace using 'name' to the
     local _config_namespaces list.
     Raises ValueError if the name already exists
     Returns the new namespace object
     '''
     if getattr(self._config_namespaces, name, None):
         raise ValueError('Config Namespace already exists for:"{0}"'
                          .format(name))
     newnamespace = Namespace()
     setattr(self._config_namespaces, name, newnamespace)
     return newnamespace
Example #35
0
    def test_install(self):
        ns = Namespace(name='namespace', data=self.valid_data)
        node = MagicMock()
        node.schedule_action = MagicMock(return_value=task_mock(('instance',
                                                                 'nsName')))
        ns.api = MagicMock()
        ns.api.services.get = MagicMock(return_value=node)
        args = {
            'disktype': ns.data['diskType'].upper(),
            'mode': ns.data['mode'],
            'password': ns.data['password'],
            'public': ns.data['public'],
            'size': ns.data['size'],
            'name': ns.data['nsName']
        }
        ns.install()

        node.schedule_action.assert_called_once_with('create_zdb_namespace',
                                                     args)
        ns.state.check('actions', 'install', 'ok')
        assert ns.data['nsName'] == 'nsName'
        assert ns.data['zerodb'] == 'instance'
Example #36
0
 def test_uninstall(self):
     ns = Namespace(name='namespace', data=self.valid_data)
     ns.data['nsName'] = 'nsName'
     ns.state.set('actions', 'install', 'ok')
     ns.api = MagicMock()
     ns.uninstall()
     ns._zerodb.schedule_action.assert_called_once_with(
         'namespace_delete', args={'name': 'nsName'})
Example #37
0
	def display_in_html(self, out, url):
		#get template
		path = os.path.join(os.path.dirname(__file__), 'empty.html')
		f = open(path)
		try:
			data = f.read()
		finally:
			f.close()
		#Edit title and subtitle in html and shadow titlers
		data = self.__replace_chunk(data, "<title>", "</title>", self.title + ' - ' + self.subtitle)
		data = re.sub(r'SiteTitle: "My TiddlyWiki"', 'SiteTitle: "'+self.title+'"', data)
		data = re.sub(r'SiteSubtitle: "a reusable non-linear personal web notebook"', 'SiteSubtitle: "'+self.subtitle+'"', data )
		data = re.sub(r'SiteUrl: "http://www\.tiddlywiki\.com/"', 'SiteUrl: "'+url+'"', data )
		#Update markupBlock
		data = self.__update_markup_block(data, "PRE-HEAD","MarkupPreHead")
		data = self.__update_markup_block(data, "POST-HEAD","MarkupPostHead")
		data = self.__update_markup_block(data, "PRE-BODY","MarkupPreBody")
		data = self.__update_markup_block(data, "POST-SCRIPT","MarkupPostBody")
			
		#find storearea and insert tiddlers	
		match = re.match("^(.*?<div id=\"storeArea\">).*?(</div>.*?<!--POST-STOREAREA-->.*?)$", data, re.DOTALL)
		if match:
			begin = match.group(1)
			end = match.group(2)
			out.write(begin)
			tiddlers = {}
			for t in self.tiddlers:
				if t:
					tiddler = Tiddler.get(t)
					if tiddler:
						tiddlers[tiddler.title] = tiddler
			# add dynamic tiddlywiki
			if 'UploadTiddlerPlugin' not in tiddlers:
				tiddlers['UploadTiddlerPlugin'] = Namespace.get_tiddler('UploadTiddlerPlugin')
			tiddler = None
			if self.namespace.own_by(User.get_current_user()):
				tiddler = Tiddler.create_or_update(self.namespace, 'zzTiddlyHomeTweaks', self.owner.username, tags='systemConfig excludeLists excludeSearch', 
					newTitle='zzTiddlyHomeTweaks', 
					text= config.tweaks_tiddler%{'username': self.owner.username, 'filename': self.name, 'storeUrl': config.storeTiddler_url})
				tiddlers['zzTiddlyHomeTweaks'] = tiddler
				keys = tiddlers.keys()
				keys.sort()
			for ti in keys:
				if ti:
					out.write(tiddlers[ti].displayInStorearea(self.name))
			out.write(end)
			
			if tiddler:
				tiddler.delete()
		else:
			raise Error("Maformed empty.html file")
Example #38
0
class Polygon(KMLObject):
    defaults = Namespace(
        name='',
        description='',
        styleUrl='',
        altitudeMode='relativeToGround',
        tessellate='1',
        outerBoundary='',
        innerBoundary='',
        extrude=0,
        data='',
        LookAt=None,
    )

    def __init__(self,
                 outerBoundary,
                 innerBoundary=None,
                 style=None,
                 **kwargs):
        outerBoundary = _OuterBoundary(outerBoundary)

        self.args = Polygon.defaults.copy()
        self.args.update(**kwargs)
        self.args.update(outerBoundary=outerBoundary.write())
        self.data = Data()

        if style:
            self.style = style
            self.args.update(styleUrl=style.tag)

        if innerBoundary:
            innerBoundary = _InnerBoundary(innerBoundary)
            self.args.update(innerBoundary=innerBoundary.write())

    def add_data(self, data):
        if hasattr(data, '__iter__'):
            for dta in data:
                self.data.add_data_field(dta)
        else:
            self.data.add_data_field(data)

    def write(self):
        print "Writing polygon", self.args.name
        lookat = self.args.LookAt
        if lookat:
            lookat = lookat.write()
        else:
            lookat = ''
        self.args.update(LookAt=lookat)
        self.args.update(data=self.data.write())
        return Formats.Polygon.format(**self.args.asdict())
Example #39
0
class LineStyle(KMLObject):
    defaults = Namespace(
        colour='ffffffff',
        id='StyleID',
        width=2,
    )

    def __init__(self, **kwargs):
        self.args = LineStyle.defaults
        self.args.update(**kwargs)
        self.tag = Formats.StyleUrl.format(url=self.args.id)

    def write(self):
        return Formats.LineStyle.format(**self.args.asdict())
Example #40
0
    def testValidVariableNames(self):
        ns = Namespace()

        ns['value'] = 'this is fine'
        ns['flag:value'] = 'this is fine'
        ns[':declaring_flag'] = 'this is fine'

        with pytest.raises(InvalidNamespaceKeyName):
            ns.__setitem__('', 'this will not work')
        with pytest.raises(InvalidNamespaceKeyName):
            ns.__setitem__(':', 'this will not work')
        with pytest.raises(InvalidNamespaceKeyName):
            ns.__setitem__('flag:', 'this will not work')
    def __init__(self, file=stderr):
        # Contains scope-depth. this is different from scope level, because
        # the scopes are uniquely defined, while depths are often the same
        self._depth = 0

        # the SymbolTable is a hash of type: {SymbolName :String -> {ScopeLevel :int -> (Name, Type, Var, Depth) }}
        self._symbolHash = {}

        # Current depth is stored as _scopelevelstack[-1]
        self._scopelevelstack=[0]
        self._allscopes=[0]

        self.errors = False
        self.output = file

        # Namespace instance for symbol table
        self.namespace = Namespace()
Example #42
0
    def testNegativeFlags(self):
        '''
        Using negative flags
        '''
        ns = Namespace(flags=['win32'])
        ns._DeclareFlag('win32', 'Windows-OS')
        ns['win32:variable'] = 'Windows'
        ns['!win32:variable'] = 'NotWindows'
        assert ns.GetValue('variable', as_string=True) == 'Windows'

        ns = Namespace()
        ns._DeclareFlag('win32', 'Windows-OS')
        ns['win32:variable'] = 'Windows'
        ns['!win32:variable'] = 'NotWindows'
        assert ns.GetValue('variable', as_string=True) == 'NotWindows'
Example #43
0
 def __init__(self, base_dir=None, name="simplecli"):
     self.name = name
     self.logger = Logger(name=name, level=INFO)
     handler = StreamHandler(sys.stdout)
     handler.setLevel(DEBUG)
     handler.setFormatter(Formatter(magenta("[%(asctime)s]%(message)s")))
     self.logger.addHandler(handler)
     self._config_namespaces = Namespace()
     self.menu_cache = []
     self.completer_context = None
     self.base_dir = base_dir or os.path.expanduser("~/.simplecli")
     if os.path.exists(self.base_dir):
         if not os.path.isdir(self.base_dir):
             raise ValueError('base dir provided is not a dir:"{0}'.format(self.base_dir))
     else:
         os.makedirs(self.base_dir)
     self.simplecli_config_file = os.path.join(self.base_dir, str(name) + ".config")
     self.simplecli_config = None
     self.init_simplecli_config()
     self._setup_stdio()
     self._load_plugin_menus()
Example #44
0
    def __init__(
        self,
        definition_source=None,
        values_source_list=None,
        argv_source=None,
        # use_config_files=True,
        use_auto_help=True,
        use_admin_controls=True,
        quit_after_admin=True,
        options_banned_from_help=None,
        app_name="",
        app_version="",
        app_description="",
        config_pathname=".",
    ):
        """create and initialize a configman object.

        parameters:
          definition_source - a namespace or list of namespaces from which
                              configman is to fetch the definitions of the
                              configuration parameters.
          values_source_list - (optional) a hierarchical list of sources for
                               values for the configuration parameters.
                               As values are copied from these sources,
                               conficting values are resolved with sources
                               on the right getting preference over sources on
                               the left.
          argv_source - if the values_source_list contains a commandline
                        source, this value is an alternative source for
                        actual command line arguments.  Useful for testing or
                        preprocessing command line arguments.
          use_auto_help - set to True if configman is to automatically set up
                          help output for command line invocations.
          use_admin_controls - configman can add command line flags that it
                               interprets independently of the app defined
                               arguments.  True enables this capability, while,
                               False supresses it.
          quit_after_admin - if True and admin controls are enabled and used,
                             call sys.exit to end the app.  This is useful to
                             stop the app from running if all that was done
                             was to write a config file or stop after help.
          options_banned_from_help - a list of strings that will censor the
                                     output of help to prevent specified
                                    options from being listed in the help
                                    output.  This is useful for hiding debug
                                    or secret command line arguments.
          app_name - assigns a name to the app.  This is used in help output
                     and as a default basename for config files.
          app_version - assigns a version for the app used help output.
          app_description - assigns a description for the app to be used in
                            the help output.
          config_pathname - a hard coded path to the directory of or the full
                            path and name of the configuration file."""
        # instead of allowing mutables as default keyword argument values...
        if definition_source is None:
            definition_source_list = []
        elif isinstance(definition_source, collections.Sequence) and not isinstance(definition_source, basestring):
            definition_source_list = list(definition_source)
        else:
            definition_source_list = [definition_source]

        if argv_source is None:
            argv_source = sys.argv[1:]
        if options_banned_from_help is None:
            options_banned_from_help = ["admin.application"]
        self.config_pathname = config_pathname

        self.app_name = app_name
        self.app_version = app_version
        self.app_description = app_description

        self.args = []  # extra commandline arguments that are not switches
        # will be stored here.

        self._config = None  # eventual container for DOM-like config object

        self.argv_source = argv_source
        self.option_definitions = Namespace()
        self.definition_source_list = definition_source_list

        if values_source_list is None:
            # nothing set, assume defaults
            if use_admin_controls:
                values_source_list = (cm.ConfigFileFutureProxy, cm.environment, cm.command_line)
            else:
                values_source_list = (cm.environment, cm.command_line)

        admin_tasks_done = False
        self.admin_controls_list = ["help", "admin.conf", "admin.dump_conf", "admin.print_conf", "admin.application"]
        self.options_banned_from_help = options_banned_from_help

        if use_auto_help:
            self._setup_auto_help()
        if use_admin_controls:
            admin_options = self._setup_admin_options(values_source_list)
            self.definition_source_list.append(admin_options)

        # iterate through the option definitions to create the nested dict
        # hierarchy of all the options called 'option_definitions'
        for a_definition_source in self.definition_source_list:
            def_sources.setup_definitions(a_definition_source, self.option_definitions)

        if use_admin_controls:
            # some admin options need to be loaded from the command line
            # prior to processing the rest of the command line options.
            admin_options = value_sources.get_admin_options_from_command_line(self)
            # integrate the admin_options with 'option_definitions'
            self._overlay_value_sources_recurse(source=admin_options, ignore_mismatches=True)

        self.values_source_list = value_sources.wrap(values_source_list, self)

        # first pass to get classes & config path - ignore bad options
        self._overlay_value_sources(ignore_mismatches=True)

        # walk tree expanding class options
        self._walk_expanding_class_options()

        # the app_name, app_version and app_description are to come from
        # if 'admin.application' option if it is present. If it is not present,
        # get the app_name,et al, from parameters passed into the constructor.
        # if those are empty, set app_name, et al, to empty strings
        try:
            app_option = self._get_option("admin.application")
            self.app_name = getattr(app_option.value, "app_name", "")
            self.app_version = getattr(app_option.value, "app_version", "")
            self.app_description = getattr(app_option.value, "app_description", "")
        except exc.NotAnOptionError:
            # there is no 'admin.application' option, continue to use the
            # 'app_name' from the parameters passed in, if they exist.
            pass

        # second pass to include config file values - ignore bad options
        self._overlay_value_sources(ignore_mismatches=True)

        # walk tree expanding class options
        self._walk_expanding_class_options()

        # third pass to get values - complain about bad options
        self._overlay_value_sources(ignore_mismatches=False)

        if use_auto_help and self._get_option("help").value:
            self.output_summary()
            admin_tasks_done = True

        if use_admin_controls and self._get_option("admin.print_conf").value:
            self.print_conf()
            admin_tasks_done = True

        if use_admin_controls and self._get_option("admin.dump_conf").value:
            self.dump_conf()
            admin_tasks_done = True

        if quit_after_admin and admin_tasks_done:
            sys.exit()
Example #45
0
 def test_Namespace(self):
     ns = Namespace('global')
     ns.add_name('local','stuff')
     self.assertTrue('local' in ns)
     self.assertRaises(NameExists, lambda : ns.add_name('local','other stuff'))
Example #46
0
 def get_namespace (self, name):
     namespace = _lib.myelin_repository_get_namespace (self, name)
     return Namespace.from_pointer (namespace)
Example #47
0
    def __init__(self, name, functions=None, extendings=None):
        Namespace.__init__(self)

        self.name = name
        self.functions = functions if functions else {}
        self.extendings = extendings
Example #48
0
class ConfigurationManager(object):

    #--------------------------------------------------------------------------
    def __init__(self,
                 definition_source=None,
                 values_source_list=None,
                 argv_source=None,
                 #use_config_files=True,
                 use_auto_help=True,
                 use_admin_controls=True,
                 quit_after_admin=True,
                 options_banned_from_help=None,
                 app_name='',
                 app_version='',
                 app_description='',
                 config_pathname='.',
                 config_optional=True,
                 ):
        """create and initialize a configman object.

        parameters:
          definition_source - a namespace or list of namespaces from which
                              configman is to fetch the definitions of the
                              configuration parameters.
          values_source_list - (optional) a hierarchical list of sources for
                               values for the configuration parameters.
                               As values are copied from these sources,
                               conficting values are resolved with sources
                               on the right getting preference over sources on
                               the left.
          argv_source - if the values_source_list contains a commandline
                        source, this value is an alternative source for
                        actual command line arguments.  Useful for testing or
                        preprocessing command line arguments.
          use_auto_help - set to True if configman is to automatically set up
                          help output for command line invocations.
          use_admin_controls - configman can add command line flags that it
                               interprets independently of the app defined
                               arguments.  True enables this capability, while,
                               False supresses it.
          quit_after_admin - if True and admin controls are enabled and used,
                             call sys.exit to end the app.  This is useful to
                             stop the app from running if all that was done
                             was to write a config file or stop after help.
          options_banned_from_help - a list of strings that will censor the
                                     output of help to prevent specified
                                    options from being listed in the help
                                    output.  This is useful for hiding debug
                                    or secret command line arguments.
          app_name - assigns a name to the app.  This is used in help output
                     and as a default basename for config files.
          app_version - assigns a version for the app used help output.
          app_description - assigns a description for the app to be used in
                            the help output.
          config_pathname - a hard coded path to the directory of or the full
                            path and name of the configuration file.
          config_optional - a boolean indicating if a missing default config
                            file is optional.  Note: this is only for the
                            default config file.  If a config file is specified
                            on the commandline, it _must_ exsist."""

        # instead of allowing mutables as default keyword argument values...
        if definition_source is None:
            definition_source_list = []
        elif (isinstance(definition_source, collections.Sequence) and
              not isinstance(definition_source, basestring)):
            definition_source_list = list(definition_source)
        else:
            definition_source_list = [definition_source]

        if argv_source is None:
            self.argv_source = sys.argv[1:]
            self.app_invocation_name = sys.argv[0]
        else:
            self.argv_source = argv_source
            self.app_invocation_name = app_name
        if options_banned_from_help is None:
            options_banned_from_help = ['application']
        self.config_pathname = config_pathname
        self.config_optional = config_optional

        self.app_name = app_name
        self.app_version = app_version
        self.app_description = app_description

        self.args = []  # extra commandline arguments that are not switches
                        # will be stored here.

        self._config = None  # eventual container for DOM-like config object

        self.option_definitions = Namespace()
        self.definition_source_list = definition_source_list

        if values_source_list is None:
            # nothing set, assume defaults
            if use_admin_controls:
                values_source_list = (cm.ConfigFileFutureProxy,
                                      cm.environment,
                                      cm.command_line)
            else:
                values_source_list = (cm.environment,
                                      cm.command_line)

        admin_tasks_done = False
        self.admin_controls_list = ['help',
                                    'admin.conf',
                                    'admin.dump_conf',
                                    'admin.print_conf',
                                    'admin.migration',
                                    'admin.strict'
                                    ]
        self.options_banned_from_help = options_banned_from_help

        if use_auto_help:
            self._setup_auto_help()
        if use_admin_controls:
            admin_options = self._setup_admin_options(values_source_list)
            self.definition_source_list.append(admin_options)

        # iterate through the option definitions to create the nested dict
        # hierarchy of all the options called 'option_definitions'
        for a_definition_source in self.definition_source_list:
            try:
                safe_copy_of_def_source = a_definition_source.safe_copy()
            except AttributeError:
                # apparently, the definition source was not in the form of a
                # Namespace object.  This isn't a show stopper, but we don't
                # know how to make a copy of this object safely: we know from
                # experience that the stock copy.copy method leads to grief
                # as many sub-objects within an option definition source can
                # not be copied that way (classes, for example).
                # The only action we can take is to trust and continue with the
                # original copy of the definition source.
                safe_copy_of_def_source = a_definition_source
            def_sources.setup_definitions(safe_copy_of_def_source,
                                          self.option_definitions)

        if use_admin_controls:
            # the name of the config file needs to be loaded from the command
            # line prior to processing the rest of the command line options.
            config_filename = \
                value_sources.config_filename_from_commandline(self)
            if (
                config_filename
                and cm.ConfigFileFutureProxy in values_source_list
            ):
                self.option_definitions.admin.conf.default = config_filename

        self.values_source_list = value_sources.wrap(
            values_source_list,
            self
        )

        known_keys = self._overlay_expand()
        self._check_for_mismatches(known_keys)

        # the app_name, app_version and app_description are to come from
        # if 'application' option if it is present. If it is not present,
        # get the app_name,et al, from parameters passed into the constructor.
        # if those are empty, set app_name, et al, to empty strings
        try:
            app_option = self._get_option('application')
            self.app_name = getattr(app_option.value, 'app_name', '')
            self.app_version = getattr(app_option.value, 'app_version', '')
            self.app_description = getattr(app_option.value,
                                           'app_description', '')
        except exc.NotAnOptionError:
            # there is no 'application' option, continue to use the
            # 'app_name' from the parameters passed in, if they exist.
            pass

        if use_auto_help and self._get_option('help').value:
            self.output_summary()
            admin_tasks_done = True

        if use_admin_controls and self._get_option('admin.print_conf').value:
            self.print_conf()
            admin_tasks_done = True

        if use_admin_controls and self._get_option('admin.dump_conf').value:
            self.dump_conf()
            admin_tasks_done = True

        if quit_after_admin and admin_tasks_done:
            sys.exit()

    #--------------------------------------------------------------------------
    @contextlib.contextmanager
    def context(self):
        """return a config as a context that calls close on every item when
        it goes out of scope"""
        config = None
        try:
            config = self.get_config()
            yield config
        finally:
            if config:
                self._walk_and_close(config)

    #--------------------------------------------------------------------------
    def get_config(self, mapping_class=DotDictWithAcquisition):
        config = self._generate_config(mapping_class)
        if self._aggregate(self.option_definitions, config, config):
            # state changed, must regenerate
            return self._generate_config(mapping_class)
        else:
            return config

    #--------------------------------------------------------------------------
    def output_summary(self,
                       output_stream=sys.stdout,
                       block_password=True):
        """outputs a usage tip and the list of acceptable commands.
        This is useful as the output of the 'help' option.

        parameters:
            output_stream - an open file-like object suitable for use as the
                            target of a print statement
            block_password - a boolean driving the use of a string of * in
                             place of the value for any object containing the
                             substring 'passowrd'
        """
        if self.app_name or self.app_description:
            print >> output_stream, 'Application:',
        if self.app_name:
            print >> output_stream, self.app_name, self.app_version
        if self.app_description:
            print >> output_stream, self.app_description
        if self.app_name or self.app_description:
            print >> output_stream, ''

        names_list = self.get_option_names()
        print >> output_stream, "usage:\n", self.app_invocation_name, \
                                "[OPTIONS]...",
        bracket_count = 0
        for key in names_list:
            an_option = self.option_definitions[key]
            if an_option.is_argument:
                if an_option.default is None:
                    print >> output_stream, an_option.name,
                else:
                    print >> output_stream, "[ %s" % an_option.name,
                    bracket_count += 1
        print >> output_stream, ']' * bracket_count, '\n'

        names_list.sort()
        if names_list:
            print >> output_stream, 'OPTIONS:'

        pad = ' ' * 4

        for name in names_list:
            if name in self.options_banned_from_help:
                continue
            option = self._get_option(name)

            line = ' ' * 2  # always start with 2 spaces
            if option.short_form:
                line += '-%s, ' % option.short_form
            line += '--%s' % name
            line += '\n'

            doc = option.doc if option.doc is not None else ''
            if doc:
                line += '%s%s\n' % (pad, doc)
            try:
                value = option.value
                type_of_value = type(value)
                converter_function = conv.to_string_converters[type_of_value]
                default = converter_function(value)
            except KeyError:
                default = option.value
            if default is not None:
                if 'password' in name.lower():
                    default = '*********'
                if name not in ('help',):
                    # don't bother with certain dead obvious ones
                    line += '%s(default: %s)\n' % (pad, default)

            print >> output_stream, line

    #--------------------------------------------------------------------------
    def print_conf(self):
        """write a config file to the pathname specified in the parameter.  The
        file extention determines the type of file written and must match a
        registered type.

        parameters:
            config_pathname - the full path and filename of the target config
                               file."""

        config_file_type = self._get_option('admin.print_conf').value

        @contextlib.contextmanager
        def stdout_opener():
            yield sys.stdout

        skip_keys = [k for (k, v)
                     in self.option_definitions.iteritems()
                     if isinstance(v, Option) and v.exclude_from_print_conf]
        self.write_conf(config_file_type, stdout_opener, skip_keys=skip_keys)

    #--------------------------------------------------------------------------
    def dump_conf(self, config_pathname=None):
        """write a config file to the pathname specified in the parameter.  The
        file extention determines the type of file written and must match a
        registered type.

        parameters:
            config_pathname - the full path and filename of the target config
                               file."""

        if not config_pathname:
            config_pathname = self._get_option('admin.dump_conf').value

        opener = functools.partial(open, config_pathname, 'w')
        config_file_type = os.path.splitext(config_pathname)[1][1:]

        skip_keys = [k for (k, v)
                     in self.option_definitions.iteritems()
                     if isinstance(v, Option) and v.exclude_from_dump_conf]

        self.write_conf(config_file_type, opener, skip_keys=skip_keys)

    #--------------------------------------------------------------------------
    def write_conf(self, config_file_type, opener, skip_keys=None):
        """write a configuration file to a file-like object.

        parameters:
            config_file_type - a string containing a registered file type OR
                               a for_XXX module from the value_source
                               package.  Passing in an string that is
                               unregistered will result in a KeyError
            opener - a callable object or function that returns a file like
                     object that works as a context in a with statement."""

        blocked_keys = self.admin_controls_list
        if skip_keys:
            blocked_keys.extend(skip_keys)

        if blocked_keys:
            option_defs = self.option_definitions.safe_copy()
            for a_blocked_key in blocked_keys:
                try:
                    del option_defs[a_blocked_key]
                except (AttributeError, KeyError):
                    # okay that key isn't here
                    pass
            # remove empty namespaces
            all_keys = [k for k in
                        option_defs.keys_breadth_first(include_dicts=True)]
            for key in all_keys:
                candidate = option_defs[key]
                if (isinstance(candidate, Namespace) and not len(candidate)):
                    del option_defs[key]
        else:
            option_defs = self.option_definitions

        if self.option_definitions.admin.migration.default:
            self._migrate_options_for_acquisition(option_defs)

        value_sources.write(config_file_type,
                            option_defs,
                            opener)

    #--------------------------------------------------------------------------
    @staticmethod
    def _migrate_options_for_acquisition(option_defs):
        """sift through the definitions looking for common keys that can be
        migrated to a lower level in the hierarchy.

        create a mapping with these characteristics:
            key - composed of the values from Option objects for 'name',
                  'default' and 'from_string' converstion function.
            value - a list of the the keys from the currently active option
                    definition.

        this implements a reverse index of value to keys for the system of
        Namespaces and Options that make up the configuration manager's
        option definition mapping.

        the mapping is keyed by the option name, its default value and
        the from_string_converter function.  If all these things are the
        same in two options, then it is considered that they are referring
        to the same option. This means that that option may be able migrate to
        a lower level.  The mitigating factor is the number of Options with
        the same key name.  If there is more than one with the same name,
        then the Option cannot migrate to a lower level.
        """
        migration_candidates = collections.defaultdict(list)
        option_name_counts = collections.defaultdict(int)
        # cycle through all the keys
        for option_name in option_defs.keys_breadth_first():
            # option_name is a fully qualified key:  x.y.z
            an_option = option_defs[option_name]
            if isinstance(an_option, Option):
                name_default_converter_key = (
                    an_option.name,
                    str(an_option.default),
                    str(an_option.from_string_converter)
                )
                if name_default_converter_key not in migration_candidates:
                    option_name_counts[an_option.name] += 1
                migration_candidates[name_default_converter_key].append(
                    option_name
                )
        for candidate, original_keys in migration_candidates.iteritems():
            # candidate is: (option_name, option_default, option_coverter)
            # remove name qualifications:  x.y.z --> z
            if (
                option_name_counts[candidate[0]] == 1
                and len(original_keys) > 1
            ):
                option_defs[candidate[0]] = \
                    option_defs[original_keys[0]].copy()
                option_defs[candidate[0]].not_for_definition = True
                for a_key in original_keys:
                    option_defs[a_key].comment_out = True

    #--------------------------------------------------------------------------
    def log_config(self, logger):
        """write out the current configuration to a log-like object.

        parameters:
            logger - a object that implements a method called 'info' with the
                     same semantics as the call to 'logger.info'"""

        logger.info("app_name: %s", self.app_name)
        logger.info("app_version: %s", self.app_version)
        logger.info("current configuration:")
        config = [(key, self.option_definitions[key].value)
                  for key in self.option_definitions.keys_breadth_first()
                  if key not in self.admin_controls_list]
        config.sort()
        for key, val in config:
            if 'password' in key.lower():
                logger.info('%s: *********', key)
            else:
                try:
                    logger.info('%s: %s', key,
                                conv.to_string_converters[type(key)](val))
                except KeyError:
                    logger.info('%s: %s', key, val)

    #--------------------------------------------------------------------------
    def get_option_names(self):
        """returns a list of fully qualified option names.

        returns:
            a list of strings representing the Options in the source Namespace
            list.  Each item will be fully qualified with dot delimited
            Namespace names.
        """
        return [x for x in self.option_definitions.keys_breadth_first()
                if isinstance(self.option_definitions[x], Option)]

    #--------------------------------------------------------------------------
    def _overlay_expand(self):
        """This method overlays each of the value sources onto the default
        in each of the defined options.  It does so using a breadth first
        iteration, overlaying and expanding each level of the tree in turn.
        As soon as no changes were made to any level, the loop breaks and the
        work is done.  The actual action of the overlay is to take the value
        from the source and copy into the 'default' member of each Option
        object.

        "expansion" means converting an option value into its real type from
        string. The conversion is accomplished by simply calling the
        'set_value' method of the Option object.  If the resultant type has its
        own configuration options, bring those into the current namespace and
        then proceed to overlay/expand those.
        """
        new_keys_discovered = True  # loop control, False breaks the loop
        known_keys = set()  # a set of keys that have been expanded

        while new_keys_discovered:  # loop until nothing more is done
            # keys holds a list of all keys in the option definitons in
            # breadth first order using this form: [ 'x', 'y', 'z', 'x.a',
            # 'x.b', 'z.a', 'z.b', 'x.a.j', 'x.a.k', 'x.b.h']
            keys = [x for x in self.option_definitions.keys_breadth_first()]
            new_keys_discovered = False  # setup to break loop

            # overlay process:
            # fetch all the default values from the value sources before
            # applying the from string conversions
            for key in keys:
                if key not in known_keys:  # skip all keys previously seen
                    # loop through all the value sources looking for values
                    # that match this current key.
                    for a_value_source in self.values_source_list:
                        try:
                            # get all the option values from this value source
                            val_src_dict = a_value_source.get_values(
                                self,
                                True
                            )
                            # make sure it is in the form of a DotDict
                            if not isinstance(val_src_dict, DotDict):
                                val_src_dict = \
                                    DotDictWithAcquisition(val_src_dict)
                            # get the Option for this key
                            opt = self.option_definitions[key]
                            # overlay the default with the new value from
                            # the value source.  This assignment may come
                            # via acquisition, so the key given may not have
                            # been an exact match for what was returned.
                            opt.default = val_src_dict[key]
                        except KeyError, x:
                            pass  # okay, that source doesn't have this value

            # expansion process:
            # step through all the keys converting them to their proper
            # types and bringing in any new keys in the process
            for key in keys:
                if key not in known_keys:  # skip all keys previously seen
                    # mark this key as having been seen and processed
                    known_keys.add(key)
                    an_option = self.option_definitions[key]
                    if isinstance(an_option, Aggregation):
                        continue  # aggregations are ignored
                    # apply the from string conversion to make the real value
                    an_option.set_value(an_option.default)
                    # new values have been seen, don't let loop break
                    new_keys_discovered = True
                    try:
                        try:
                            # try to fetch new requirements from this value
                            new_req = an_option.value.get_required_config()
                        except AttributeError:
                            new_req = an_option.value.required_config
                        # make sure what we got as new_req is actually a
                        # Mapping of some sort
                        if not isinstance(new_req, collections.Mapping):
                            # we didn't get a mapping, perhaps the option value
                            # was a Mock object - in any case we can't try to
                            # interpret 'new_req' as a configman requirement
                            # collection.  We must abandon processing this
                            # option further
                            continue
                        # get the parent namespace
                        current_namespace = self.option_definitions.parent(key)
                        if current_namespace is None:
                            # we're at the top level, use the base namespace
                            current_namespace = self.option_definitions
                        # add the new Options to the namespace
                        current_namespace.update(new_req.safe_copy())
                    except AttributeError, x:
                        # there are apparently no new Options to bring in from
                        # this option's value
                        pass
Example #49
0
    def __init__(self,
                 definition_source=None,
                 values_source_list=None,
                 argv_source=None,
                 #use_config_files=True,
                 use_auto_help=True,
                 use_admin_controls=True,
                 quit_after_admin=True,
                 options_banned_from_help=None,
                 app_name='',
                 app_version='',
                 app_description='',
                 config_pathname='.',
                 config_optional=True,
                 ):
        """create and initialize a configman object.

        parameters:
          definition_source - a namespace or list of namespaces from which
                              configman is to fetch the definitions of the
                              configuration parameters.
          values_source_list - (optional) a hierarchical list of sources for
                               values for the configuration parameters.
                               As values are copied from these sources,
                               conficting values are resolved with sources
                               on the right getting preference over sources on
                               the left.
          argv_source - if the values_source_list contains a commandline
                        source, this value is an alternative source for
                        actual command line arguments.  Useful for testing or
                        preprocessing command line arguments.
          use_auto_help - set to True if configman is to automatically set up
                          help output for command line invocations.
          use_admin_controls - configman can add command line flags that it
                               interprets independently of the app defined
                               arguments.  True enables this capability, while,
                               False supresses it.
          quit_after_admin - if True and admin controls are enabled and used,
                             call sys.exit to end the app.  This is useful to
                             stop the app from running if all that was done
                             was to write a config file or stop after help.
          options_banned_from_help - a list of strings that will censor the
                                     output of help to prevent specified
                                    options from being listed in the help
                                    output.  This is useful for hiding debug
                                    or secret command line arguments.
          app_name - assigns a name to the app.  This is used in help output
                     and as a default basename for config files.
          app_version - assigns a version for the app used help output.
          app_description - assigns a description for the app to be used in
                            the help output.
          config_pathname - a hard coded path to the directory of or the full
                            path and name of the configuration file.
          config_optional - a boolean indicating if a missing default config
                            file is optional.  Note: this is only for the
                            default config file.  If a config file is specified
                            on the commandline, it _must_ exsist."""

        # instead of allowing mutables as default keyword argument values...
        if definition_source is None:
            definition_source_list = []
        elif (isinstance(definition_source, collections.Sequence) and
              not isinstance(definition_source, basestring)):
            definition_source_list = list(definition_source)
        else:
            definition_source_list = [definition_source]

        if argv_source is None:
            self.argv_source = sys.argv[1:]
            self.app_invocation_name = sys.argv[0]
        else:
            self.argv_source = argv_source
            self.app_invocation_name = app_name
        if options_banned_from_help is None:
            options_banned_from_help = ['application']
        self.config_pathname = config_pathname
        self.config_optional = config_optional

        self.app_name = app_name
        self.app_version = app_version
        self.app_description = app_description

        self.args = []  # extra commandline arguments that are not switches
                        # will be stored here.

        self._config = None  # eventual container for DOM-like config object

        self.option_definitions = Namespace()
        self.definition_source_list = definition_source_list

        if values_source_list is None:
            # nothing set, assume defaults
            if use_admin_controls:
                values_source_list = (cm.ConfigFileFutureProxy,
                                      cm.environment,
                                      cm.command_line)
            else:
                values_source_list = (cm.environment,
                                      cm.command_line)

        admin_tasks_done = False
        self.admin_controls_list = ['help',
                                    'admin.conf',
                                    'admin.dump_conf',
                                    'admin.print_conf',
                                    'admin.migration',
                                    'admin.strict'
                                    ]
        self.options_banned_from_help = options_banned_from_help

        if use_auto_help:
            self._setup_auto_help()
        if use_admin_controls:
            admin_options = self._setup_admin_options(values_source_list)
            self.definition_source_list.append(admin_options)

        # iterate through the option definitions to create the nested dict
        # hierarchy of all the options called 'option_definitions'
        for a_definition_source in self.definition_source_list:
            try:
                safe_copy_of_def_source = a_definition_source.safe_copy()
            except AttributeError:
                # apparently, the definition source was not in the form of a
                # Namespace object.  This isn't a show stopper, but we don't
                # know how to make a copy of this object safely: we know from
                # experience that the stock copy.copy method leads to grief
                # as many sub-objects within an option definition source can
                # not be copied that way (classes, for example).
                # The only action we can take is to trust and continue with the
                # original copy of the definition source.
                safe_copy_of_def_source = a_definition_source
            def_sources.setup_definitions(safe_copy_of_def_source,
                                          self.option_definitions)

        if use_admin_controls:
            # the name of the config file needs to be loaded from the command
            # line prior to processing the rest of the command line options.
            config_filename = \
                value_sources.config_filename_from_commandline(self)
            if (
                config_filename
                and cm.ConfigFileFutureProxy in values_source_list
            ):
                self.option_definitions.admin.conf.default = config_filename

        self.values_source_list = value_sources.wrap(
            values_source_list,
            self
        )

        known_keys = self._overlay_expand()
        self._check_for_mismatches(known_keys)

        # the app_name, app_version and app_description are to come from
        # if 'application' option if it is present. If it is not present,
        # get the app_name,et al, from parameters passed into the constructor.
        # if those are empty, set app_name, et al, to empty strings
        try:
            app_option = self._get_option('application')
            self.app_name = getattr(app_option.value, 'app_name', '')
            self.app_version = getattr(app_option.value, 'app_version', '')
            self.app_description = getattr(app_option.value,
                                           'app_description', '')
        except exc.NotAnOptionError:
            # there is no 'application' option, continue to use the
            # 'app_name' from the parameters passed in, if they exist.
            pass

        if use_auto_help and self._get_option('help').value:
            self.output_summary()
            admin_tasks_done = True

        if use_admin_controls and self._get_option('admin.print_conf').value:
            self.print_conf()
            admin_tasks_done = True

        if use_admin_controls and self._get_option('admin.dump_conf').value:
            self.dump_conf()
            admin_tasks_done = True

        if quit_after_admin and admin_tasks_done:
            sys.exit()
Example #50
0
    def testDelValue(self):
        # Level 1: Deleting a value from NamespaceVAlue
        nv = NamespaceValue()
        nv.SetValueWithFlags(('alpha',), 'ALPHA')
        nv.SetValueWithFlags(('bravo',), 'BRAVO')

        assert nv.GetValueWithFlags(('alpha',)) == 'ALPHA'
        assert nv.GetValueWithFlags(('bravo',)) == 'BRAVO'

        nv.DelValueWithFlags(('alpha',))

        assert nv.GetValueWithFlags(('alpha',)) is None
        assert nv.GetValueWithFlags(('bravo',)) == 'BRAVO'

        # Level 2: Deleting a value from the namespace.

        n = Namespace()
        n[':alpha'] = 'ALPHA'
        n[':bravo'] = 'BRAVO'
        n[':charlie'] = 'CHARLIE'

        n['var'] = 'value'
        n['alpha:var'] = 'value-alpha'
        n['bravo:var'] = 'value-bravo'

        assert n['var'] == 'value'
        assert n['alpha:var'] == 'value-alpha'
        assert n['bravo:var'] == 'value-bravo'
        assert n['charlie:var'] == 'value'

        del n['alpha:var']

        assert n['var'] == 'value'
        assert n['alpha:var'] == 'value'
        assert n['bravo:var'] == 'value-bravo'
        assert n['charlie:var'] == 'value'

        n.ClearValue('var')

        with pytest.raises(NamespaceKeyError):
            n.__getitem__('var')
        with pytest.raises(NamespaceKeyError):
            n.__getitem__('alpha:var')
        with pytest.raises(NamespaceKeyError):
            n.__getitem__('bravo:var')
        with pytest.raises(NamespaceKeyError):
            n.__getitem__('bravo:var')
        with pytest.raises(NamespaceKeyError):
            n.__getitem__('charlie:var')
Example #51
0
    def __init__(self, name):
        Namespace.__init__(self)

        self.parent_namespace = None

        self._name = name
Example #52
0
class ConfigurationManager(object):

    # --------------------------------------------------------------------------
    def __init__(
        self,
        definition_source=None,
        values_source_list=None,
        argv_source=None,
        # use_config_files=True,
        use_auto_help=True,
        use_admin_controls=True,
        quit_after_admin=True,
        options_banned_from_help=None,
        app_name="",
        app_version="",
        app_description="",
        config_pathname=".",
    ):
        """create and initialize a configman object.

        parameters:
          definition_source - a namespace or list of namespaces from which
                              configman is to fetch the definitions of the
                              configuration parameters.
          values_source_list - (optional) a hierarchical list of sources for
                               values for the configuration parameters.
                               As values are copied from these sources,
                               conficting values are resolved with sources
                               on the right getting preference over sources on
                               the left.
          argv_source - if the values_source_list contains a commandline
                        source, this value is an alternative source for
                        actual command line arguments.  Useful for testing or
                        preprocessing command line arguments.
          use_auto_help - set to True if configman is to automatically set up
                          help output for command line invocations.
          use_admin_controls - configman can add command line flags that it
                               interprets independently of the app defined
                               arguments.  True enables this capability, while,
                               False supresses it.
          quit_after_admin - if True and admin controls are enabled and used,
                             call sys.exit to end the app.  This is useful to
                             stop the app from running if all that was done
                             was to write a config file or stop after help.
          options_banned_from_help - a list of strings that will censor the
                                     output of help to prevent specified
                                    options from being listed in the help
                                    output.  This is useful for hiding debug
                                    or secret command line arguments.
          app_name - assigns a name to the app.  This is used in help output
                     and as a default basename for config files.
          app_version - assigns a version for the app used help output.
          app_description - assigns a description for the app to be used in
                            the help output.
          config_pathname - a hard coded path to the directory of or the full
                            path and name of the configuration file."""
        # instead of allowing mutables as default keyword argument values...
        if definition_source is None:
            definition_source_list = []
        elif isinstance(definition_source, collections.Sequence) and not isinstance(definition_source, basestring):
            definition_source_list = list(definition_source)
        else:
            definition_source_list = [definition_source]

        if argv_source is None:
            argv_source = sys.argv[1:]
        if options_banned_from_help is None:
            options_banned_from_help = ["admin.application"]
        self.config_pathname = config_pathname

        self.app_name = app_name
        self.app_version = app_version
        self.app_description = app_description

        self.args = []  # extra commandline arguments that are not switches
        # will be stored here.

        self._config = None  # eventual container for DOM-like config object

        self.argv_source = argv_source
        self.option_definitions = Namespace()
        self.definition_source_list = definition_source_list

        if values_source_list is None:
            # nothing set, assume defaults
            if use_admin_controls:
                values_source_list = (cm.ConfigFileFutureProxy, cm.environment, cm.command_line)
            else:
                values_source_list = (cm.environment, cm.command_line)

        admin_tasks_done = False
        self.admin_controls_list = ["help", "admin.conf", "admin.dump_conf", "admin.print_conf", "admin.application"]
        self.options_banned_from_help = options_banned_from_help

        if use_auto_help:
            self._setup_auto_help()
        if use_admin_controls:
            admin_options = self._setup_admin_options(values_source_list)
            self.definition_source_list.append(admin_options)

        # iterate through the option definitions to create the nested dict
        # hierarchy of all the options called 'option_definitions'
        for a_definition_source in self.definition_source_list:
            def_sources.setup_definitions(a_definition_source, self.option_definitions)

        if use_admin_controls:
            # some admin options need to be loaded from the command line
            # prior to processing the rest of the command line options.
            admin_options = value_sources.get_admin_options_from_command_line(self)
            # integrate the admin_options with 'option_definitions'
            self._overlay_value_sources_recurse(source=admin_options, ignore_mismatches=True)

        self.values_source_list = value_sources.wrap(values_source_list, self)

        # first pass to get classes & config path - ignore bad options
        self._overlay_value_sources(ignore_mismatches=True)

        # walk tree expanding class options
        self._walk_expanding_class_options()

        # the app_name, app_version and app_description are to come from
        # if 'admin.application' option if it is present. If it is not present,
        # get the app_name,et al, from parameters passed into the constructor.
        # if those are empty, set app_name, et al, to empty strings
        try:
            app_option = self._get_option("admin.application")
            self.app_name = getattr(app_option.value, "app_name", "")
            self.app_version = getattr(app_option.value, "app_version", "")
            self.app_description = getattr(app_option.value, "app_description", "")
        except exc.NotAnOptionError:
            # there is no 'admin.application' option, continue to use the
            # 'app_name' from the parameters passed in, if they exist.
            pass

        # second pass to include config file values - ignore bad options
        self._overlay_value_sources(ignore_mismatches=True)

        # walk tree expanding class options
        self._walk_expanding_class_options()

        # third pass to get values - complain about bad options
        self._overlay_value_sources(ignore_mismatches=False)

        if use_auto_help and self._get_option("help").value:
            self.output_summary()
            admin_tasks_done = True

        if use_admin_controls and self._get_option("admin.print_conf").value:
            self.print_conf()
            admin_tasks_done = True

        if use_admin_controls and self._get_option("admin.dump_conf").value:
            self.dump_conf()
            admin_tasks_done = True

        if quit_after_admin and admin_tasks_done:
            sys.exit()

    # --------------------------------------------------------------------------
    @contextlib.contextmanager
    def context(self):
        """return a config as a context that calls close on every item when
        it goes out of scope"""
        config = None
        try:
            config = self.get_config()
            yield config
        finally:
            if config:
                self._walk_and_close(config)

    # --------------------------------------------------------------------------
    def get_config(self, mapping_class=DotDictWithAcquisition):
        config = self._generate_config(mapping_class)
        if self._aggregate(self.option_definitions, config, config):
            # state changed, must regenerate
            return self._generate_config(mapping_class)
        else:
            return config

    # --------------------------------------------------------------------------
    def output_summary(self, output_stream=sys.stdout, block_password=True):
        """outputs a usage tip and the list of acceptable commands.
        This is useful as the output of the 'help' option.

        parameters:
            output_stream - an open file-like object suitable for use as the
                            target of a print statement
            block_password - a boolean driving the use of a string of * in
                             place of the value for any object containing the
                             substring 'passowrd'
        """
        if self.app_name or self.app_description:
            print >> output_stream, "Application:",
        if self.app_name:
            print >> output_stream, self.app_name, self.app_version
        if self.app_description:
            print >> output_stream, self.app_description
        if self.app_name or self.app_description:
            print >> output_stream, ""

        names_list = self.get_option_names()
        names_list.sort()
        if names_list:
            print >> output_stream, "Options:"

        for name in names_list:
            if name in self.options_banned_from_help:
                continue
            option = self._get_option(name)

            line = " " * 2  # always start with 2 spaces
            if option.short_form:
                line += "-%s, " % option.short_form
            line += "--%s" % name
            line = line.ljust(30)  # seems to the common practise

            doc = option.doc if option.doc is not None else ""
            try:
                value = option.value
                type_of_value = type(value)
                converter_function = conv.to_string_converters[type_of_value]
                default = converter_function(value)
            except KeyError:
                default = option.value
            if default is not None:
                if "password" in name.lower():
                    default = "*********"
                if doc:
                    doc += " "
                if name not in ("help",):
                    # don't bother with certain dead obvious ones
                    doc += "(default: %s)" % default

            line += doc
            print >> output_stream, line

    # --------------------------------------------------------------------------
    def print_conf(self):
        """write a config file to the pathname specified in the parameter.  The
        file extention determines the type of file written and must match a
        registered type.

        parameters:
            config_pathname - the full path and filename of the target config
                               file."""

        config_file_type = self._get_option("admin.print_conf").value

        @contextlib.contextmanager
        def stdout_opener():
            yield sys.stdout

        skip_keys = [
            k for (k, v) in self.option_definitions.iteritems() if isinstance(v, Option) and v.exclude_from_print_conf
        ]
        self.write_conf(config_file_type, stdout_opener, skip_keys=skip_keys)

    # --------------------------------------------------------------------------
    def dump_conf(self, config_pathname=None):
        """write a config file to the pathname specified in the parameter.  The
        file extention determines the type of file written and must match a
        registered type.

        parameters:
            config_pathname - the full path and filename of the target config
                               file."""

        if not config_pathname:
            config_pathname = self._get_option("admin.dump_conf").value

        opener = functools.partial(open, config_pathname, "w")
        config_file_type = os.path.splitext(config_pathname)[1][1:]

        skip_keys = [
            k for (k, v) in self.option_definitions.iteritems() if isinstance(v, Option) and v.exclude_from_dump_conf
        ]

        self.write_conf(config_file_type, opener, skip_keys=skip_keys)

    # --------------------------------------------------------------------------
    def write_conf(self, config_file_type, opener, skip_keys=None):
        """write a configuration file to a file-like object.

        parameters:
            config_file_type - a string containing a registered file type OR
                               a for_XXX module from the value_source
                               package.  Passing in an string that is
                               unregistered will result in a KeyError
            opener - a callable object or function that returns a file like
                     object that works as a context in a with statement."""

        blocked_keys = self.admin_controls_list
        if skip_keys:
            blocked_keys.extend(skip_keys)

        option_iterator = functools.partial(self._walk_config, blocked_keys=blocked_keys)
        with opener() as config_fp:
            value_sources.write(config_file_type, option_iterator, config_fp)

    # --------------------------------------------------------------------------
    def log_config(self, logger):
        """write out the current configuration to a log-like object.

        parameters:
            logger - a object that implements a method called 'info' with the
                     same semantics as the call to 'logger.info'"""

        logger.info("app_name: %s", self.app_name)
        logger.info("app_version: %s", self.app_version)
        logger.info("current configuration:")
        config = [
            (qkey, val.value)
            for qkey, key, val in self._walk_config(self.option_definitions)
            if qkey not in self.admin_controls_list and not isinstance(val, Namespace)
        ]
        config.sort()
        for key, val in config:
            if "password" in key.lower():
                logger.info("%s: *********", key)
            else:
                try:
                    logger.info("%s: %s", key, conv.to_string_converters[type(key)](val))
                except KeyError:
                    logger.info("%s: %s", key, val)

    # --------------------------------------------------------------------------
    def get_option_names(self, source=None, names=None, prefix=""):
        """returns a list of fully qualified option names.

        parameters:
            source - a sequence of Namespace of Options, usually not specified,
                     If not specified, the function will default to using the
                     internal list of Option definitions.
            names - a list to start with for appending the lsit Option names.
                    If ommited, the function will start with an empty list.

        returns:
            a list of strings representing the Options in the source Namespace
            list.  Each item will be fully qualified with dot delimited
            Namespace names.
        """
        if not source:
            source = self.option_definitions
        if names is None:
            names = []
        for key, val in source.items():
            if isinstance(val, Namespace):
                new_prefix = "%s%s." % (prefix, key)
                self.get_option_names(val, names, new_prefix)
            elif isinstance(val, Option):
                names.append("%s%s" % (prefix, key))
            # skip aggregations, we want only Options
        return names

    # --------------------------------------------------------------------------
    @staticmethod
    def _walk_and_close(a_dict):
        for val in a_dict.itervalues():
            if isinstance(val, collections.Mapping):
                ConfigurationManager._walk_and_close(val)
            if hasattr(val, "close") and not inspect.isclass(val):
                val.close()

    # --------------------------------------------------------------------------
    def _generate_config(self, mapping_class):
        """This routine generates a copy of the DotDict based config"""
        config = mapping_class()
        self._walk_config_copy_values(self.option_definitions, config, mapping_class)
        return config

    # --------------------------------------------------------------------------
    def _walk_expanding_class_options(self, source_namespace=None, parent_namespace=None):
        if source_namespace is None:
            source_namespace = self.option_definitions
        expanded_keys = []
        expansions_were_done = True
        while expansions_were_done:
            expansions_were_done = False
            # can't use iteritems in loop, we're changing the dict
            for key, val in source_namespace.items():
                if isinstance(val, Namespace):
                    self._walk_expanding_class_options(source_namespace=val, parent_namespace=source_namespace)
                elif key not in expanded_keys and (inspect.isclass(val.value) or inspect.ismodule(val.value)):
                    expanded_keys.append(key)
                    expansions_were_done = True
                    if key == "application":
                        target_namespace = parent_namespace
                    else:
                        target_namespace = source_namespace
                    try:
                        for o_key, o_val in val.value.get_required_config().iteritems():
                            target_namespace.__setattr__(o_key, copy.deepcopy(o_val))
                    except AttributeError:
                        pass  # there are no required_options for this class
                else:
                    pass  # don't need to touch other types of Options
            self._overlay_value_sources(ignore_mismatches=True)

    # --------------------------------------------------------------------------
    def _setup_auto_help(self):
        help_option = Option(name="help", doc="print this", default=False)
        self.definition_source_list.append({"help": help_option})

    # --------------------------------------------------------------------------
    def _get_config_pathname(self):
        if os.path.isdir(self.config_pathname):
            # we've got a path with no file name at the end
            # use the appname as the file name and default to an 'ini'
            # config file type
            if self.app_name:
                return os.path.join(self.config_pathname, "%s.ini" % self.app_name)
            else:
                # there is no app_name yet
                # we'll punt and use 'config'
                return os.path.join(self.config_pathname, "config.ini")
        return self.config_pathname

    # --------------------------------------------------------------------------
    def _setup_admin_options(self, values_source_list):
        base_namespace = Namespace()
        base_namespace.admin = admin = Namespace()
        admin.add_option(
            name="print_conf",
            default=None,
            doc="write current config to stdout (%s)" % ", ".join(value_sources.file_extension_dispatch.keys()),
        )
        admin.add_option(name="dump_conf", default="", doc="a pathname to which to write the current config")
        # only offer the config file admin options if they've been requested in
        # the values source list
        if ConfigFileFutureProxy in values_source_list:
            default_config_pathname = self._get_config_pathname()
            admin.add_option(
                name="conf", default=default_config_pathname, doc="the pathname of the config file " "(path/filename)"
            )
        return base_namespace

    # --------------------------------------------------------------------------
    def _overlay_value_sources(self, ignore_mismatches=True):
        for a_settings_source in self.values_source_list:
            try:
                this_source_ignore_mismatches = ignore_mismatches or a_settings_source.always_ignore_mismatches
            except AttributeError:
                # the settings source doesn't have the concept of always
                # ignoring mismatches, so the original value of
                # ignore_mismatches stands
                this_source_ignore_mismatches = ignore_mismatches
            options = a_settings_source.get_values(self, ignore_mismatches=this_source_ignore_mismatches)
            self._overlay_value_sources_recurse(options, ignore_mismatches=this_source_ignore_mismatches)

    # --------------------------------------------------------------------------
    def _overlay_value_sources_recurse(self, source, destination=None, prefix="", ignore_mismatches=True):
        if destination is None:
            destination = self.option_definitions
        for key, val in source.items():
            try:
                sub_destination = destination
                for subkey in key.split("."):
                    sub_destination = sub_destination[subkey]
            except KeyError:
                if ignore_mismatches:
                    continue
                if key == subkey:
                    raise exc.NotAnOptionError("%s is not an option" % key)
                raise exc.NotAnOptionError("%s subpart %s is not an option" % (key, subkey))
            except TypeError:
                pass
            if isinstance(sub_destination, Namespace):
                self._overlay_value_sources_recurse(val, sub_destination, prefix=("%s.%s" % (prefix, key)))
            elif isinstance(sub_destination, Option):
                sub_destination.set_value(val)
            elif isinstance(sub_destination, Aggregation):
                # there is nothing to do for Aggregations at this time
                # it appears here anyway as a marker for future enhancements
                pass

    # --------------------------------------------------------------------------
    def _walk_config_copy_values(self, source, destination, mapping_class):
        for key, val in source.items():
            value_type = type(val)
            if isinstance(val, Option) or isinstance(val, Aggregation):
                destination[key] = val.value
            elif value_type == Namespace:
                destination[key] = d = mapping_class()
                self._walk_config_copy_values(val, d, mapping_class)

    # --------------------------------------------------------------------------
    def _aggregate(self, source, base_namespace, local_namespace):
        aggregates_found = False
        for key, val in source.items():
            if isinstance(val, Namespace):
                new_aggregates_found = self._aggregate(val, base_namespace, local_namespace[key])
                aggregates_found = new_aggregates_found or aggregates_found
            elif isinstance(val, Aggregation):
                val.aggregate(base_namespace, local_namespace, self.args)
                aggregates_found = True
            # skip Options, we're only dealing with Aggregations
        return aggregates_found

    # --------------------------------------------------------------------------
    @staticmethod
    def _option_sort(x_tuple):
        key, val = x_tuple
        if isinstance(val, Namespace):
            return "zzzzzzzzzzz%s" % key
        else:
            return key

    # --------------------------------------------------------------------------
    @staticmethod
    def _block_password(qkey, key, value, block_password=True):
        if block_password and "password" in key.lower():
            value = "*********"
        return qkey, key, value

    # --------------------------------------------------------------------------
    def _walk_config(self, source=None, prefix="", blocked_keys=(), block_password=False):
        if source == None:
            source = self.option_definitions
        options_list = source.items()
        options_list.sort(key=ConfigurationManager._option_sort)
        for key, val in options_list:
            qualified_key = "%s%s" % (prefix, key)
            if qualified_key in blocked_keys:
                continue
            if isinstance(val, Option):
                yield self._block_password(qualified_key, key, val, block_password)
            if isinstance(val, Aggregation):
                yield qualified_key, key, val
            elif isinstance(val, Namespace):
                if qualified_key == "admin":
                    continue
                yield qualified_key, key, val
                new_prefix = "%s%s." % (prefix, key)
                for xqkey, xkey, xval in self._walk_config(val, new_prefix, blocked_keys, block_password):
                    yield xqkey, xkey, xval

    # --------------------------------------------------------------------------
    def _get_option(self, name):
        source = self.option_definitions
        try:
            for sub_name in name.split("."):
                candidate = source[sub_name]
                if isinstance(candidate, Option):
                    return candidate
                else:
                    source = candidate
        except KeyError:
            pass  # we need to raise the exception below in either case
            # of a key error or execution falling through the loop
        raise exc.NotAnOptionError("%s is not a known option name" % name)

    # --------------------------------------------------------------------------
    def _get_options(self, source=None, options=None, prefix=""):
        if not source:
            source = self.option_definitions
        if options is None:
            options = []
        for key, val in source.items():
            if isinstance(val, Namespace):
                new_prefix = "%s%s." % (prefix, key)
                self._get_options(val, options, new_prefix)
            else:
                options.append(("%s%s" % (prefix, key), val))
        return options
Example #53
0
class BaseEnv:
    """
    The intention of this class is to hold environment variables which might be
    global to the tool, it's menus, and the command executed within.
    """

    def __init__(self, base_dir=None, name="simplecli"):
        self.name = name
        self.logger = Logger(name=name, level=INFO)
        handler = StreamHandler(sys.stdout)
        handler.setLevel(DEBUG)
        handler.setFormatter(Formatter(magenta("[%(asctime)s]%(message)s")))
        self.logger.addHandler(handler)
        self._config_namespaces = Namespace()
        self.menu_cache = []
        self.completer_context = None
        self.base_dir = base_dir or os.path.expanduser("~/.simplecli")
        if os.path.exists(self.base_dir):
            if not os.path.isdir(self.base_dir):
                raise ValueError('base dir provided is not a dir:"{0}'.format(self.base_dir))
        else:
            os.makedirs(self.base_dir)
        self.simplecli_config_file = os.path.join(self.base_dir, str(name) + ".config")
        self.simplecli_config = None
        self.init_simplecli_config()
        self._setup_stdio()
        self._load_plugin_menus()

    def _setup_stdio(self):
        def _get_stdio(name):
            if hasattr(sys, name):
                return getattr(sys, name)
            else:
                return open(name, "wa")

        if self.simplecli_config.default_input:
            self.default_input = _get_stdio(self.simplecli_config.default_input)
        else:
            self.default_input = sys.stdin
        if self.simplecli_config.default_output:
            self.default_output = _get_stdio(self.simplecli_config.default_output)
        else:
            self.default_output = sys.stdout
        if self.simplecli_config.default_error:
            self.default_error = _get_stdio(self.simplecli_config.default_error)
        else:
            self.default_error = sys.stderr

    def init_simplecli_config(self):
        simplecli = Config(config_file_path=self.simplecli_config_file, name="simplecli")
        simplecli.debug = False
        simplecli.history_file = os.path.join(self.base_dir, "history")
        simplecli.page_break = True
        simplecli.plugin_dir = None

        simplecli.default_input = "stdin"  # ie stdin
        simplecli.default_output = "stdout"  # ie stdout or stderr
        simplecli.default_error = "stderr"  # ie stderr
        simplecli.prompt_method = None  # define this method as a global way to
        # construct menu prompts
        simplecli.path_delimeter = ">"  # Used for constructing the default
        # prompt and displayed path string(s)
        simplecli._update_from_file(markers=["main"])
        self.add_config_to_namespace(namespace_name="main", config=simplecli, create=True)
        # Assign to local var for easy access as well
        self.simplecli_config = simplecli

    def add_namespace(self, name):
        """
        Adds a blank configuration namespace using 'name' to the
        local _config_namespaces list.
        Raises ValueError if the name already exists
        Returns the new namespace object
        """
        if getattr(self._config_namespaces, name, None):
            raise ValueError('Config Namespace already exists for:"{0}"'.format(name))
        newnamespace = Namespace()
        setattr(self._config_namespaces, name, newnamespace)
        return newnamespace

    def get_namespace(self, name, create=False):
        """
        Will retrieve an existing namespace object of 'name' if found.
        If not found and 'create == True' then a new namespace obj will be
        created, added to self._config_namespaces and returned.
        """

        if isinstance(name, basestring):
            name = [name]
        if not isinstance(name, list):
            raise ValueError('Bad value passed for "name" to get_namespace, got:"{0}/{1}"'.format(name, type(name)))
        context = self._config_namespaces
        for n in name:
            last = context
            context = getattr(context, n, None)
            if not context and create:
                context = Namespace()
                setattr(last, n, context)
        return context

    def get_config_for_namespace(self, item_name, namespace_path=None):
        """
        Attempts to get a config object from the specified namespace
        :param item_name: string, name of Config to fetch
        :param namespace_path: string, or list of strings representing the heirarchy/location
                                of the namespace to fetch config from
        returns Config obj
        """
        if namespace_path is None:
            namespace_path = ["main"]
        if not isinstance(namespace_path, list):
            namespace_path = [namespace_path]
        namespace_path.append(item_name)
        context = self._config_namespaces
        for ns in namespace_path:
            context = getattr(context, ns, None)
            if not context:
                raise ValueError(
                    'Namespace:"{0}" does not exist within path:{1}'.format(
                        ns, ".".join(str(x) for x in namespace_path)
                    )
                )
        return context

    def add_config_to_namespace(self, namespace_name, config, force=False, create=False):
        """
        Attempts to add a config object to the specified namespace
        :param namespace_name: string, name of namespace to fetch config from
        :param config: Config() obj to add to namespace named 'namespace_name'
        :param force: boolean, will replace existing config block in namespace
        :param create: bollean, will create namespace if it does not exist
        """
        assert isinstance(namespace_name, str)
        context = self.get_namespace(namespace_name, create=create)
        assert config.name, "block_name was not populated"
        if getattr(context, config.name, None) and not force:
            raise AttributeError(
                "Base env already has config at context:"
                '"{0}", name:"{1}" use force to replace '
                "this section".format(namespace_name, config.name)
            )
        setattr(context, config.name, config)

    def save_config(self, path=None):
        path = path or self.simplecli_config_file
        backup_path = path + ".bak"
        config_json = self._config_namespaces._to_json()
        if os.path.isfile(path):
            copyfile(path, backup_path)
        save_file = file(path, "w")
        with save_file:
            save_file.write(config_json)
            save_file.flush()

    def _load_plugin_menus(self):
        """
        Loads plugin menus found either in the provided plugin directory
        or the current working dir. Will attempt to load files starting
        with 'menu'. See plugin menu_examples for more info.
        """

        self.plugin_menus = []
        return
        plugin_dir = self.simplecli_config.plugin_dir or os.path.curdir
        for file in os.listdir(plugin_dir):
            if os.path.isfile(file) and file.startswith("menu") and file.endswith(".py"):
                full_path = os.path.join(plugin_dir, file)
                p_name = os.path.basename(file).rstrip(".py")
                plugmod = imp.load_source(p_name, full_path)
                menuclass = getattr(plugmod, "menu_class", None)
                if not menuclass:
                    raise AttributeError(
                        '"{0}". Plugin conf does not have '
                        'a "menu_class" attribute. See plugin'
                        "example for info.".format(full_path)
                    )
                plugin = menuclass(env=self)
                existing_menu = self.get_cached_menu_by_class(plugin.__class__)
                if existing_menu:
                    raise RuntimeError(
                        "Duplicate Menu Classes found while"
                        'loading plugins: class:"{0}", '
                        'menu:"{1}", plugin:"{2}", file:"{3}"'.format(
                            plugin.__class__, existing_menu.name, plugin.name, full_path
                        )
                    )
                parent_menus = getattr(plugmod, "parent_menus", None)
                if parent_menus:
                    plugin._parents = parent_menus
                self.plugin_menus.append(plugin)

    def get_cached_menu_by_class(self, menuclass, list=None):
        """
        Returns a loaded menu instance matching the provided class.
        """
        list = list or self.menu_cache
        for item in self.menu_cache:
            if item.__class__ == menuclass:
                return item
        return None

    def get_formatted_conf(self, block=None):
        """
        Returns a json representation of the current configuration.
        """
        ret_buf = ""
        if not block:
            namespace = self._config_namespaces
        else:
            namespace = self.get_namespace(block, create=False)
        if namespace:
            ret_buf = namespace._to_json()
        return ret_buf

    def get_config_diff(self, file_path=None):
        """
        Method to show current values vs those (saved) in a file.
        Will return a formatted string to show the difference
        """
        # Create formatted string representation of dict values
        text1 = self._config_namespaces._to_json().splitlines()
        # Create formatted string representation of values in file
        file_path = file_path or self.simplecli_config_file
        file_dict = get_dict_from_file(file_path=file_path) or {}
        text2 = json.dumps(file_dict, sort_keys=True, indent=4).splitlines()
        diff = difflib.unified_diff(text2, text1, lineterm="")
        return "\n".join(diff)

    def get_menu_by_name(self, name, list=None):
        list = list or self.menu_cache
        for menu in list:
            if menu.name == name:
                return menu
        return None
Example #54
0
from scene import *
from namespace import Namespace

data = Namespace()

data.dfontsize = 25
data.dfontfamily = "Monofur"

data.dtilesize = Size(128, 128) # Tile size on iPad 3
data.dtilecolour = (0, 0.8, 0)

data.dstrokecolour = (0.01, 0.21, 0.286)
data.dstrokeweight = 1

data.dbgcolour   = (0.01, 0.21, 0.286)

data.boardsize   = (4, 4)
data.pstart      = Point(200, 700)
data.pbwidth     = 5
data.dpbbg       = (0, 0.196, 1)

data.UP          = 1
data.DOWN        = 2
data.LEFT        = 3
data.RIGHT       = 4

data.BDBG = (1.0, 1.0, 1.0) # Button Default BackGround
data.BPBG = (0.8, 0.8, 0.8) # Button Pressed BackGround

data.TDFG = (0.0, 0.0, 0.0) # Text Default ForeGround
data.TPFG = (0.0, 0.0, 0.0) # Text Pressed ForeGround
class SymbolTable:
    def __init__(self, file=stderr):
        # Contains scope-depth. this is different from scope level, because
        # the scopes are uniquely defined, while depths are often the same
        self._depth = 0

        # the SymbolTable is a hash of type: {SymbolName :String -> {ScopeLevel :int -> (Name, Type, Var, Depth) }}
        self._symbolHash = {}

        # Current depth is stored as _scopelevelstack[-1]
        self._scopelevelstack=[0]
        self._allscopes=[0]

        self.errors = False
        self.output = file

        # Namespace instance for symbol table
        self.namespace = Namespace()

    def prettyprint(self, file=stdout):
        for name in self._symbolHash:
            print("%s:" % name, end='', file=file)
            for scope in self._symbolHash[name]:
                print("\t\t%i: %s" % (scope, str(self._symbolHash[name][scope])), file=file)

    def getCurrentScopeStack(self):
        return self._scopelevelstack

    def getCurrentScope(self):
        return self._scopelevelstack[0]

    def __str__(self):
        return str(self._symbolHash)

    def openScope(self):
        self._depth += 1

        nextScope = max(self._allscopes)+1
        # print("New scope: %i" % nextScope)
        self._scopelevelstack.insert(0, nextScope)
        self._allscopes.append(nextScope)

    def closeScope(self):
        self._depth -= 1

        self._scopelevelstack.pop(0)

    def retrieveScope(self, symbol, level=-1, stack=None):
        '''Returns the symbol-table entry for the symbol at the specified level.
           If no level is specified, then the inner-most level is used'''
        if stack is None:
            stack = self._scopelevelstack

        if symbol not in self._symbolHash:
            return None

        if level >= 0:
            if level not in self._symbolHash[symbol]:
                return None
            else:
                return self._symbolHash[symbol][level]
        else:
            # level == -1. Return the inner-most entry
            for scope in stack:
                # print("Checking for %s in scope %i" % (symbol, scope))
                if scope in self._symbolHash[symbol]:
                    # print("Returning", self._symbolHash[symbol][scope])
                    return self._symbolHash[symbol][scope]
            # print("Could not find %s" % symbol)
            return None

    # TODO: Type??
    def enterSymbol(self, name, symtype):
        if symtype is None:
            print("Trying to enter %s with a NONE symtype" % name, file=stderr)

        if name not in self._symbolHash:
            self._symbolHash[name] = {}

        if name in self._symbolHash:
            if self._scopelevelstack[0] in self._symbolHash[name]:
                # This variable was previously defined for the scope
                print("Variable %s was already defined in scope %i" % (name, self._scopelevelstack[0]) , file=self.output)
                self.errors = True

        # print("Making %s at scope=%i, depth=%i" % (name, self._scopelevelstack[-1], self._depth))
        # Use python's global intern to compress string-names into an intern (Same thing as our NameSpace)
        newSym = SymEntry(name=self.namespace.addName(name), symtype=symtype, scope=self._scopelevelstack[0], depth=self._depth)

        self._symbolHash[name][newSym.scope] = newSym

    def createMemoryMap(self):
        # Makes a default memory map that has globals allocated
        return MemoryMap(self)