Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

admin: add unset command #1556

Merged
merged 4 commits into from
Sep 6, 2019
Merged

Conversation

HumorBaby
Copy link
Contributor

@HumorBaby HumorBaby commented Apr 11, 2019

If the value to be set is ever literally 'None' (string), then the setting is set to actual NoneType None. When a true None is set to a config attribute, the setting will essentially be reset to the default value. I feel this should be the expected behavior; i.e., a user should not be able to set a null value for something with a default, because presumably, that default is there for a reason.


Testing: (see #1554 for steps)

# admin_set_test.py
...
class AdminSetTestSection(StaticSection):
    test_setting = ValidatedAttribute('test_setting', default=None)
    test_list = ListAttribute('test_list', default=['a','b','c'])
...
@sopel.module._privmsg
@sopel.module.commands('ast-show')
def show(bot, trigger):
    bot.say('repr: "{}", type: "{}"'.format(
        repr(bot.config.admin_set_test.test_setting),
        type(bot.config.admin_set_test.test_setting)
    ))
    bot.say('repr: "{}", type: "{}"'.format(
        repr(bot.config.admin_set_test.test_list),
        type(bot.config.admin_set_test.test_list)
    ))
# _See_ current setting value
<HumorBaby>  .set admin_set_test.test_setting
<testbot>  HumorBaby: admin_set_test.test_setting = None

# See repr and type of setting
<HumorBaby>  .ast-show
<testbot>  repr: "None", type: "<type 'NoneType'>"

# Set a random value to setting
<HumorBaby>  .set admin_set_test.test_setting abc123

# Confirm change
<HumorBaby>  .set admin_set_test.test_setting
<testbot>  HumorBaby: admin_set_test.test_setting = abc123
<HumorBaby>  .ast-show
<testbot>  repr: "u'abc123'", type: "<type 'unicode'>"

# Try to "delete"/unset setting
<HumorBaby>  .set admin_set_test.test_setting None

# Confirm change
<HumorBaby>  .set admin_set_test.test_setting
<testbot>  HumorBaby: admin_set_test.test_setting = None
# everything looks okay...

# It is!
<HumorBaby>  .ast-show
<testbot>  repr: "None", type: "<type 'NoneType'>"
# Test the `ListAttribute` type
<HumorBaby>  .set admin_set_test.test_list
<testbot>  HumorBaby: admin_set_test.test_list = [u'a', u'b', u'c']
<HumorBaby>  .ast-show
<testbot>  repr: "[u'a', u'b', u'c']", type: "<type 'list'>"

# Change the list
<HumorBaby>  .set admin_set_test.test_list 1,2,3
<HumorBaby>  .set admin_set_test.test_list
<testbot>  HumorBaby: admin_set_test.test_list = [u'1', u'2', u'3']
<HumorBaby>  .ast-show
<testbot>  repr: "[u'1', u'2', u'3']", type: "<type 'list'>"

# Unset the list
<HumorBaby>  .set admin_set_test.test_list None
<HumorBaby>  .set admin_set_test.test_list
<testbot>  HumorBaby: admin_set_test.test_list = [u'a', u'b', u'c']
<HumorBaby>  .ast-show
<testbot>  repr: "[u'a', u'b', u'c']", type: "<type 'list'>"

Fixes #1554

@Exirel
Copy link
Contributor

Exirel commented Apr 11, 2019

Issue #1554 raises valid concern about how .set work, and the lack of "unset a config value". However, what you do here is a hack that relies on the interpretation of a string that may or may not be what the user actually wants. So I'm not on board with this solution.

IMHO, I'd rather have .unset section.option to remove the option and .reset section.option to set its value to its default value, and no way to set it to None (as-in the NoneType object None which make no sense for a configuration file that is all about strings).

@HumorBaby
Copy link
Contributor Author

However, what you do here is a hack that relies on the interpretation of a string that may or may not be what the user actually wants. So I'm not on board with this solution.

I'm with you completely. I felt a little uneasy when I was doing it, but somehow I ignore my instincts and convinced myself it was okay 😅

no way to set it to None (as-in the NoneType object None which make no sense for a configuration file that is all about strings).

Yes, I agree 😄 If a string None is present in the config, then it will be interpreted as a string, as expected. Thus, it makes no sense to try to set a NoneType None to a configuration setting and expecting it to be written/saved that way.

Also, given how setting values are pulled from a config object, just means that a None value will return the default for that setting. If a truly None value is desired, then it must be the default for that item. If there is a non-None default, and a user wants to set a None value to the setting, it will not be possible to save that value to config. Another point: I cannot think of a setting that would need to be nullified when the default value is non-None. Overall, this relates to your point:

.unset section.option to remove the option and .reset section.option to set its value to its default value

There is no real meaning to having removed an option. It will just return the default. And because setting a value to None will also return the default, I don't see a reason to have .unset and .reset as they will have the same result. I think .unset is the better option to keep here, just because it is more parallel to the .set terminology.

@HumorBaby
Copy link
Contributor Author

Since this is a relatively large change... changing to master, but not rebasing to hopefully avoid conflicts once 6.6.x is merged in.

@HumorBaby HumorBaby changed the base branch from 6.6.x to master April 11, 2019 23:32
@dgw
Copy link
Member

dgw commented Apr 11, 2019

I definitely think adding an .unset command is the way to go, but handling both commands in the same function (and defining all the logic to manipulate the config inside that function) is… kinda ew.

Not that I have any modules that look at trigger.group(1) to see how they're being called… but they're much simpler. This gets pretty complex by trying to do everything in one place. 😅

@HumorBaby
Copy link
Contributor Author

but handling both commands in the same function (and defining all the logic to manipulate the config inside that function) is… kinda ew.

Yea... was trying to minimize duplication of the section and option parsing. Refactor coming soon, then.

@Exirel
Copy link
Contributor

Exirel commented Apr 12, 2019

Refactor coming soon, then.

That's the way to go! 👍

@HumorBaby HumorBaby force-pushed the 1554-fix-admin-set-None branch from 38a2352 to 2ab336f Compare April 12, 2019 13:53
@HumorBaby
Copy link
Contributor Author

Refactor coming soon.

'tis here.

@HumorBaby HumorBaby changed the title admin: .set literal string None argument as NoneType admin: add unset command Apr 12, 2019
@HumorBaby HumorBaby added Bugfix Generally, PRs that reference (and fix) one or more issue(s) Feature labels Apr 12, 2019
@dgw dgw added this to the 7.0.0 milestone Apr 12, 2019
@dgw
Copy link
Member

dgw commented Apr 12, 2019

I guess I'll come back to this in a few days, after 6.6.x is merged into master and you can rebase. 😁

@dgw
Copy link
Member

dgw commented Apr 15, 2019

Ready to rebase; I merged 6.6.x into master just now.

@HumorBaby HumorBaby force-pushed the 1554-fix-admin-set-None branch from 2ab336f to f8779e1 Compare April 15, 2019 20:02
@HumorBaby
Copy link
Contributor Author

🎉

@dgw dgw self-requested a review April 15, 2019 20:07
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Control flow is key!

sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
@HumorBaby HumorBaby requested a review from Exirel April 21, 2019 12:51
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost done. 👍

sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is at nitpick stage. 🎉

sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
sopel/modules/admin.py Outdated Show resolved Hide resolved
@dgw
Copy link
Member

dgw commented Sep 3, 2019

Nitpicks have been addressed! 🎉 Now there's just a squash (of the fixup commits) and a rebase (to resolve the conflicts introduced on master) before final review & approval. 👍

Previously, there was no feedback from the bot on successful
`set`/`unset`. This led to some confusion during testing. Now, the bot
will `say` "OK... " upon successful setting/unsetting of an option.
Additionally, viewing an option will also show the value `type` to
avoid issues like differentiating between `= None (NoneType)` and `=
None (str)`, where one may have intentionally set `None` as a `str`, or
accidentally set `None` while trying to clear/unset an option.
@HumorBaby HumorBaby force-pushed the 1554-fix-admin-set-None branch from bc8ff2d to 01bcf40 Compare September 3, 2019 14:21
@HumorBaby
Copy link
Contributor Author

Now there's just a squash (of the fixup commits) and a rebase (to resolve the conflicts introduced on master) before final review & approval. 👍

Done.

Copy link
Member

@dgw dgw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Thanks for the rebase!

@dgw dgw requested a review from Exirel September 4, 2019 22:06
Copy link
Contributor

@Exirel Exirel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

I've a small question about how to display the InvalidSection and InvalidSectionOption, you can try and see if it can be better, or you can ignore it, it's fine by me.

sopel/modules/admin.py Show resolved Hide resolved
sopel/modules/admin.py Show resolved Hide resolved
@dgw dgw merged commit 91488be into sopel-irc:master Sep 6, 2019
@HumorBaby HumorBaby deleted the 1554-fix-admin-set-None branch May 7, 2020 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bugfix Generally, PRs that reference (and fix) one or more issue(s) Feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

admin: .set cannot clear values
3 participants