Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 08/08/14 11:04, Matthew Booth wrote: > On 07/08/14 18:54, Kevin L. Mitchell wrote: >> On Thu, 2014-08-07 at 17:46 +0100, Matthew Booth wrote: In any case, the operative point is that CONF. must >>> always be evaluated inside run-time code, never at module load time. >>> >>> ...unless you call register_opts() safely, which is what I'm >>> proposing. >> >> No, calling register_opts() at a different point only fixes the import >> issue you originally complained about; it does not fix the problem that >> the configuration option is evaluated at the wrong time. The example >> code you included in your original email evaluates the configuration >> option at module load time, BEFORE the configuration has been loaded, >> which means that the argument default will be the default of the >> configuration option, rather than the configured value of the >> configuration option. Configuration options must be evaluated at >> RUN-TIME, after configuration is loaded; they must not be evaluated at >> LOAD-TIME, which is what your original code does. > > Ah, thanks, Kevin. The pertinent information is that the config has not > been loaded at module import time, and you'll therefore always get a > default. Ironically, the specific instance which prompted this investigation[1] is in a driver. As drivers are imported dynamically after the config has been loaded, using a config variable in import context will actually work as intended. Relying on that behaviour seems pretty nasty to me, though. We could probably do with a guideline on this. I did a quick scan of Nova and found 12 instances which aren't in a driver which appear to be broken due to this at first glance, resulting in 11 config variables whose specified values appear to be ignored. Bug here: https://bugs.launchpad.net/nova/+bug/1354403 Matt [1] https://review.openstack.org/#/c/104145/14/nova/virt/vmwareapi/vmware_images.py -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 19:02, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 17:41 +0100, Matthew Booth wrote: >> ... or arg is an object which defines __nonzero__(), or defines >> __getattr__() and then explodes because of the unexpected lookup of a >> __nonzero__ attribute. Or it's False (no quotes when printed by the >> debugger), but has a unicode type and therefore evaluates to True[1]. > > If you're passing such exotic objects as parameters that could > potentially be drawn from configuration instead, maybe that code needs > to be refactored a bit :) > >> However, if you want to compare a value with None and write 'foo is >> None' it will always do exactly what you expect, regardless what you >> pass to it. I think it's also nicer to the reviewer and the >> maintainer, >> who then don't need to go looking for context to check if anything >> invalid might be passed in. > > In the vast majority of cases, however, we use a value that evaluates to > False to indicate "use the default", where "default" may be drawn from > configuration. Yes, there are cases where we must treat, say, 0 as > distinct from None, but when we don't need to, we should keep the code > as simple as possible. After all, I doubt anyone would seriously > suggest that we must always use something like the "_unset" sentinel, > even when None has no special meaning… I've found a few bugs in Openstack by checking implicit boolean tests while reviewing code. Here's a recent one: https://review.openstack.org/#/c/109006/1/nova/db/sqlalchemy/api.py Note that the caller has accidentally passed read_deleted=False, a pretty easy mistake to make, and the bare object test has hidden that error and silently replaced it with a default. Also note that while PEP8 stops short of decreeing against bare object tests, it does recommend against it. See the section 'Programming Recommendations': http://legacy.python.org/dev/peps/pep-0008/ Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 18:54, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 17:46 +0100, Matthew Booth wrote: >>> In any case, the operative point is that CONF. must >> always be >>> evaluated inside run-time code, never at module load time. >> >> ...unless you call register_opts() safely, which is what I'm >> proposing. > > No, calling register_opts() at a different point only fixes the import > issue you originally complained about; it does not fix the problem that > the configuration option is evaluated at the wrong time. The example > code you included in your original email evaluates the configuration > option at module load time, BEFORE the configuration has been loaded, > which means that the argument default will be the default of the > configuration option, rather than the configured value of the > configuration option. Configuration options must be evaluated at > RUN-TIME, after configuration is loaded; they must not be evaluated at > LOAD-TIME, which is what your original code does. Ah, thanks, Kevin. The pertinent information is that the config has not been loaded at module import time, and you'll therefore always get a default. Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, Aug 7, 2014 at 12:54 PM, Kevin L. Mitchell < kevin.mitch...@rackspace.com> wrote: > On Thu, 2014-08-07 at 17:46 +0100, Matthew Booth wrote: > > > In any case, the operative point is that CONF. must > > always be > > > evaluated inside run-time code, never at module load time. > > > > ...unless you call register_opts() safely, which is what I'm > > proposing. > > No, calling register_opts() at a different point only fixes the import > issue you originally complained about; it does not fix the problem that > the configuration option is evaluated at the wrong time. The example > code you included in your original email evaluates the configuration > option at module load time, BEFORE the configuration has been loaded, > which means that the argument default will be the default of the > configuration option, rather than the configured value of the > configuration option. Configuration options must be evaluated at > RUN-TIME, after configuration is loaded; they must not be evaluated at > LOAD-TIME, which is what your original code does. > -- > Kevin L. Mitchell > Rackspace > We had this problem in Keystone[1]. There were some config parameters passed to a function decorator (it was the cache timeout time). You'd change the value in the config file and it would have no effect... the default was still used. Luckily the cache decorator also took a function so it was an easy fix, just pass `lambda: CONF.foo`. The mistaken code was made possible because the config options were registered at import time. Keystone now registers its config options at run-time so using CONF.foo at import-time fails with an error that the option isn't registered. [1] https://bugs.launchpad.net/keystone/+bug/1265670 - Brant ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Aug 7, 2014, at 12:39 PM, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 17:27 +0100, Matthew Booth wrote: >> On 07/08/14 16:27, Kevin L. Mitchell wrote: >>> On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: A (the?) solution is to register_opts() in foo before importing any modules which might also use oslo.config. >>> >>> Actually, I disagree. The real problem here is the definition of >>> bar_func(). The default value of the parameter "arg" will likely always >>> be the default value of foo_opt, rather than the configured value, >>> because "CONF.foo_opt" will be evaluated at module load time. The way >>> bar_func() should be defined would be: >>> >>>def bar_func(arg=None): >>>if not arg: >>>arg = CONF.foo_opt >>>… >>> >>> That ensures that arg will be the configured value, and should also >>> solve the import conflict. >> >> That's different behaviour, because you can no longer pass arg=None. The >> fix isn't to change the behaviour of the code. > > Well, the point is that the code as written is incorrect. And if 'None' > is an input you want to allow, then use an incantation like: > >_unset = object() > >def bar_func(arg=_unset): >if arg is _unset: >arg = CONF.foo_opt >… > > In any case, the operative point is that CONF. must always be > evaluated inside run-time code, never at module load time. It would be even better to take the extra step of registering the option at runtime at the point it is about to be used by calling register_opt() inside bar_func() instead of when bar is imported. That avoids import order concerns, and re-enforces the idea that options should be declared local to the code that uses them and their values should be passed to other code, rather than having 2 modules tightly bound together through a global configuration value. Doug ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 17:41 +0100, Matthew Booth wrote: > ... or arg is an object which defines __nonzero__(), or defines > __getattr__() and then explodes because of the unexpected lookup of a > __nonzero__ attribute. Or it's False (no quotes when printed by the > debugger), but has a unicode type and therefore evaluates to True[1]. If you're passing such exotic objects as parameters that could potentially be drawn from configuration instead, maybe that code needs to be refactored a bit :) > However, if you want to compare a value with None and write 'foo is > None' it will always do exactly what you expect, regardless what you > pass to it. I think it's also nicer to the reviewer and the > maintainer, > who then don't need to go looking for context to check if anything > invalid might be passed in. In the vast majority of cases, however, we use a value that evaluates to False to indicate "use the default", where "default" may be drawn from configuration. Yes, there are cases where we must treat, say, 0 as distinct from None, but when we don't need to, we should keep the code as simple as possible. After all, I doubt anyone would seriously suggest that we must always use something like the "_unset" sentinel, even when None has no special meaning… -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 17:46 +0100, Matthew Booth wrote: > > In any case, the operative point is that CONF. must > always be > > evaluated inside run-time code, never at module load time. > > ...unless you call register_opts() safely, which is what I'm > proposing. No, calling register_opts() at a different point only fixes the import issue you originally complained about; it does not fix the problem that the configuration option is evaluated at the wrong time. The example code you included in your original email evaluates the configuration option at module load time, BEFORE the configuration has been loaded, which means that the argument default will be the default of the configuration option, rather than the configured value of the configuration option. Configuration options must be evaluated at RUN-TIME, after configuration is loaded; they must not be evaluated at LOAD-TIME, which is what your original code does. -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 17:44 +0100, Matthew Booth wrote: > These are tricky, case-by-case workarounds to a general problem which > can be solved by simply calling register_opts() in a place where it's > guaranteed to be safe. No, THE CODE IS WRONG. It is evaluating a configuration value at _module load time_ rather than at run time. It is wrong for the same reason that "def foo(arg={})" is wrong. If you fix the time at which evaluation occurs, importing is no longer a problem. > Is there any reason not to call register_opts() > before importing other modules? -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 17:39, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 17:27 +0100, Matthew Booth wrote: >> On 07/08/14 16:27, Kevin L. Mitchell wrote: >>> On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: A (the?) solution is to register_opts() in foo before importing any modules which might also use oslo.config. >>> >>> Actually, I disagree. The real problem here is the definition of >>> bar_func(). The default value of the parameter "arg" will likely always >>> be the default value of foo_opt, rather than the configured value, >>> because "CONF.foo_opt" will be evaluated at module load time. The way >>> bar_func() should be defined would be: >>> >>> def bar_func(arg=None): >>> if not arg: >>> arg = CONF.foo_opt >>> … >>> >>> That ensures that arg will be the configured value, and should also >>> solve the import conflict. >> >> That's different behaviour, because you can no longer pass arg=None. The >> fix isn't to change the behaviour of the code. > > Well, the point is that the code as written is incorrect. And if 'None' > is an input you want to allow, then use an incantation like: > > _unset = object() > > def bar_func(arg=_unset): > if arg is _unset: > arg = CONF.foo_opt > … > > In any case, the operative point is that CONF. must always be > evaluated inside run-time code, never at module load time. ...unless you call register_opts() safely, which is what I'm proposing. Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 17:34, Dan Smith wrote: >> That's different behaviour, because you can no longer pass arg=None. The >> fix isn't to change the behaviour of the code. > > So use a sentinel... That would also be a change to the behaviour of the code, because you can no longer pass in the sentinel. These are tricky, case-by-case workarounds to a general problem which can be solved by simply calling register_opts() in a place where it's guaranteed to be safe. Is there any reason not to call register_opts() before importing other modules? Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 17:11, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 10:55 -0500, Matt Riedemann wrote: >> >> On 8/7/2014 10:27 AM, Kevin L. Mitchell wrote: >>> On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: A (the?) solution is to register_opts() in foo before importing any modules which might also use oslo.config. >>> >>> Actually, I disagree. The real problem here is the definition of >>> bar_func(). The default value of the parameter "arg" will likely always >>> be the default value of foo_opt, rather than the configured value, >>> because "CONF.foo_opt" will be evaluated at module load time. The way >>> bar_func() should be defined would be: >>> >>> def bar_func(arg=None): >>> if not arg: >>> arg = CONF.foo_opt >>> … >>> >>> That ensures that arg will be the configured value, and should also >>> solve the import conflict. >>> >> >> Surely you mean: >> >> if arg is not None: >> >> right?! I'm pretty sure there is a hacking check for that now too... > > No, I meant "if not arg", which would be true if arg is None—or 0, or > empty string, or False. If those alternate false values are potential > values of arg, then clearly an "if arg is None" would be the correct > incantation. However, an "if arg is not None" would never be > appropriate for this logic :) (And the hacking check is against "if arg > == None" or "if arg != None"…) ... or arg is an object which defines __nonzero__(), or defines __getattr__() and then explodes because of the unexpected lookup of a __nonzero__ attribute. Or it's False (no quotes when printed by the debugger), but has a unicode type and therefore evaluates to True[1]. However, if you want to compare a value with None and write 'foo is None' it will always do exactly what you expect, regardless what you pass to it. I think it's also nicer to the reviewer and the maintainer, who then don't need to go looking for context to check if anything invalid might be passed in. Matt [1] I actually hit this. I still don't understand it. -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 17:27 +0100, Matthew Booth wrote: > On 07/08/14 16:27, Kevin L. Mitchell wrote: > > On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: > >> A (the?) solution is to register_opts() in foo before importing any > >> modules which might also use oslo.config. > > > > Actually, I disagree. The real problem here is the definition of > > bar_func(). The default value of the parameter "arg" will likely always > > be the default value of foo_opt, rather than the configured value, > > because "CONF.foo_opt" will be evaluated at module load time. The way > > bar_func() should be defined would be: > > > > def bar_func(arg=None): > > if not arg: > > arg = CONF.foo_opt > > … > > > > That ensures that arg will be the configured value, and should also > > solve the import conflict. > > That's different behaviour, because you can no longer pass arg=None. The > fix isn't to change the behaviour of the code. Well, the point is that the code as written is incorrect. And if 'None' is an input you want to allow, then use an incantation like: _unset = object() def bar_func(arg=_unset): if arg is _unset: arg = CONF.foo_opt … In any case, the operative point is that CONF. must always be evaluated inside run-time code, never at module load time. -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
> That's different behaviour, because you can no longer pass arg=None. The > fix isn't to change the behaviour of the code. So use a sentinel... --Dan signature.asc Description: OpenPGP digital signature ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 07/08/14 16:27, Kevin L. Mitchell wrote: > On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: >> A (the?) solution is to register_opts() in foo before importing any >> modules which might also use oslo.config. > > Actually, I disagree. The real problem here is the definition of > bar_func(). The default value of the parameter "arg" will likely always > be the default value of foo_opt, rather than the configured value, > because "CONF.foo_opt" will be evaluated at module load time. The way > bar_func() should be defined would be: > > def bar_func(arg=None): > if not arg: > arg = CONF.foo_opt > … > > That ensures that arg will be the configured value, and should also > solve the import conflict. That's different behaviour, because you can no longer pass arg=None. The fix isn't to change the behaviour of the code. Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 10:55 -0500, Matt Riedemann wrote: > > On 8/7/2014 10:27 AM, Kevin L. Mitchell wrote: > > On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: > >> A (the?) solution is to register_opts() in foo before importing any > >> modules which might also use oslo.config. > > > > Actually, I disagree. The real problem here is the definition of > > bar_func(). The default value of the parameter "arg" will likely always > > be the default value of foo_opt, rather than the configured value, > > because "CONF.foo_opt" will be evaluated at module load time. The way > > bar_func() should be defined would be: > > > > def bar_func(arg=None): > > if not arg: > > arg = CONF.foo_opt > > … > > > > That ensures that arg will be the configured value, and should also > > solve the import conflict. > > > > Surely you mean: > > if arg is not None: > > right?! I'm pretty sure there is a hacking check for that now too... No, I meant "if not arg", which would be true if arg is None—or 0, or empty string, or False. If those alternate false values are potential values of arg, then clearly an "if arg is None" would be the correct incantation. However, an "if arg is not None" would never be appropriate for this logic :) (And the hacking check is against "if arg == None" or "if arg != None"…) -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On 8/7/2014 10:27 AM, Kevin L. Mitchell wrote: On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: A (the?) solution is to register_opts() in foo before importing any modules which might also use oslo.config. Actually, I disagree. The real problem here is the definition of bar_func(). The default value of the parameter "arg" will likely always be the default value of foo_opt, rather than the configured value, because "CONF.foo_opt" will be evaluated at module load time. The way bar_func() should be defined would be: def bar_func(arg=None): if not arg: arg = CONF.foo_opt … That ensures that arg will be the configured value, and should also solve the import conflict. Surely you mean: if arg is not None: right?! I'm pretty sure there is a hacking check for that now too... :) -- Thanks, Matt Riedemann ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains
On Thu, 2014-08-07 at 12:15 +0100, Matthew Booth wrote: > A (the?) solution is to register_opts() in foo before importing any > modules which might also use oslo.config. Actually, I disagree. The real problem here is the definition of bar_func(). The default value of the parameter "arg" will likely always be the default value of foo_opt, rather than the configured value, because "CONF.foo_opt" will be evaluated at module load time. The way bar_func() should be defined would be: def bar_func(arg=None): if not arg: arg = CONF.foo_opt … That ensures that arg will be the configured value, and should also solve the import conflict. -- Kevin L. Mitchell Rackspace ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [nova][oslo] oslo.config and import chains (a proposal to update the style guidelines for imports)
On 07/08/14 12:15, Matthew Booth wrote: > I'm sure this is well known, but I recently encountered this problem for > the second time. > > --- > foo: > import oslo.config as cfg > > import bar > > CONF = cfg.CONF > CONF.register_opts('foo_opt') > > --- > bar: > import oslo.config as cfg > > CONF = cfg.CONF > > def bar_func(arg=CONF.foo_opt): > pass > --- > > importing foo results in an error in bar because CONF.foo_opt doesn't > exist. This is because bar is imported before CONF.register_opts. > CONF.import_opt() fails in the same way because it just imports foo and > hits the exact same problem when foo imports bar. > > A (the?) solution is to register_opts() in foo before importing any > modules which might also use oslo.config. This also allows import_opt() > to work in bar, which you should do to remove any dependency on import > order: > > --- > foo: > import oslo.config as cfg > > CONF = cfg.CONF > CONF.register_opts('foo_opt') > > import bar > > --- > bar: > import oslo.config as cfg > > CONF = cfg.CONF > CONF.import_opt('foo_opt', 'foo') > > def bar_func(arg=CONF.foo_opt): > pass > --- > > Even if it's old news it's worth a refresher because it was a bit of a > headscratcher. This became pertinent, because it's now blocking: https://review.openstack.org/#/c/104145/. It has a -1 for not following the style guidelines in the ordering of imports. I think we should update our style guidelines to recommend that any module which calls register_opts() or import_opt() do so *before* importing another module which might also call one of those functions. If this is done consistently, it means that any module can import_opt() from another module and be certain that it won't be re-imported itself before register_opts() has been called. Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
[openstack-dev] [nova][oslo] oslo.config and import chains
I'm sure this is well known, but I recently encountered this problem for the second time. --- foo: import oslo.config as cfg import bar CONF = cfg.CONF CONF.register_opts('foo_opt') --- bar: import oslo.config as cfg CONF = cfg.CONF def bar_func(arg=CONF.foo_opt): pass --- importing foo results in an error in bar because CONF.foo_opt doesn't exist. This is because bar is imported before CONF.register_opts. CONF.import_opt() fails in the same way because it just imports foo and hits the exact same problem when foo imports bar. A (the?) solution is to register_opts() in foo before importing any modules which might also use oslo.config. This also allows import_opt() to work in bar, which you should do to remove any dependency on import order: --- foo: import oslo.config as cfg CONF = cfg.CONF CONF.register_opts('foo_opt') import bar --- bar: import oslo.config as cfg CONF = cfg.CONF CONF.import_opt('foo_opt', 'foo') def bar_func(arg=CONF.foo_opt): pass --- Even if it's old news it's worth a refresher because it was a bit of a headscratcher. Matt -- Matthew Booth Red Hat Engineering, Virtualisation Team Phone: +442070094448 (UK) GPG ID: D33C3490 GPG FPR: 3733 612D 2D05 5458 8A8A 1600 3441 EA19 D33C 3490 ___ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev