-
Notifications
You must be signed in to change notification settings - Fork 99
Add RangeEditor support for format_func #1684
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
Conversation
…should be using format not format_str in this casee
rahulporuri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach works but I would like to see the alternative approach before choosing one over the other.
IMO, in the long term, it would be better if we deprecated and remove RangeEditor.format and just use EditorFactory.format_str. The right way to do that at the moment would be to make RangeEditor.format a property that sets RangeEditor.format_str while raising a deprecation warning.
traitsui/editors/range_editor.py
Outdated
| method uses that string for formatting. If neither attribute is | ||
| set, then this method just calls the appropriate text type to format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no mention of the format_func kwarg to the method in the docstring here.
Tangentially, the priority here seems a little wonky to me - shouldn't format_func passed to the method take priority over the format_func/format set on the factory? I think it should because format_func is being explicitly passed when calling string_value - and format_func/format might have been set on the factory at any earlier point after instantiation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this is quite strange and unexpected behavior...
I will open an issue pointing to the origin of this method (i.e. EditorFactory.string_value)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened #1695
traitsui/qt4/range_editor.py
Outdated
| high = Any() | ||
|
|
||
| #: Formatting string used to format value and labels | ||
| #: Deprecated: This trait is no longer used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking this should become a property that mirrors the editors factory_str but I don't think that is needed / allowed? (ie an instance of an editor can't set its factory's trait). We ultimately had previously just set self.format = factory.format in the init method anyways.
I am worried there may be a change in behavior if a user was to try to set format on an instance of a RangeEditor. e.g my_editor = RangeEditor(), my_editor.format = "something". Previously, because we had been using self.format throughout instead of string_value, so this would actually be used. Now, AFAICT, the best we can do is pass it as a kwarg to string_value if a user tries to set it on an instance, but that will no longer take priority if the factory has its trait set...
I don't think we want to change any behavior here (even if the current behavior is strange). I am unsure how to best move forward.
@rahulporuri any thoughts on this? I hope my explanation made some sense, if not we can discuss tomorrow at standup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So initially I expected this Test to pass on master, but fail on this branch:
def test_format_behavior_change(self):
# format trait has been deprecated in favor of format_str. However,
# behavior should be unchanged.
model = RangeModel()
with self.assertWarns(DeprecationWarning):
my_editor = RangeEditor(format="%s ...")
my_editor.format = "%s"
view = View(
Item(
"float_value",
editor=my_editor
)
)
tester = UITester()
with tester.create_ui(model, dict(view=view)) as ui:
float_value_field = tester.find_by_name(ui, "float_value")
float_value_text = float_value_field.locate(Textbox())
self.assertEqual(
float_value_text.inspect(DisplayedText()), "0.1"
)
but it passes on both. I then realized my_editor is always just an instance of the traitsui.editors.RangeEditor EditorFactory. The actual Editor instances are only created when e.g. the _get_simple_editor_class method is called. If I access the Editor directly, e.g. doing something like this:
def test_format_behavior_change(self):
# format trait has been deprecated in favor of format_str. However,
# behavior should be unchanged.
model = RangeModel()
view = View(
Item(
"float_value",
editor=RangeEditor(format="%s ...")
)
)
tester = UITester()
with tester.create_ui(model, dict(view=view)) as ui:
float_value_field = tester.find_by_name(ui, "float_value")
float_value_field._target.format = "%s"
float_value_text = float_value_field.locate(Textbox())
self.assertEqual(
float_value_text.inspect(DisplayedText()), "0.1"
)
I expected it to pass on master and fail on this branch. However, this fails on both...
So, AFAICT, behavior is not changed by this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EDIT: see the recently added test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you search for users of the format trait on this editor? I'm not even sure how one would go about specifically searching for such uses. Whether or not users exist would help us decide on whether or not we need to convert format into a property as well - and make getting/setting format raise warnings as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was unable to find any users trying to set format on the Editor instance directly.
I did see users setting it on the Factory object, ie RangeEditor(format= ...), but that is covered by the use of property/deprecation in traitsui/editors/range_editor.py.
TBH I am not certain what the pattern would be to set it on the Editor instance. I guess accessing it through UIInfo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From traitsUI docs: "Note that not every trait on every editor can react to changes: some values are only used at editor creation time; however all editors support dynamically changing the enabled, visible and invalid traits. This feature can sometimes allow developers to avoid having to create a custom Handler subclass."
traitsui/wx/range_editor.py
Outdated
| high = Any() | ||
|
|
||
| #: Formatting string used to format value and labels | ||
| #: Deprecated: This trait is no longer used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than simply commenting on the deprecation, I would like to make this a property which raises a deprecation warning.
Ideally, getting the property would return the self.factory.format_str trait, and like wise setting it would set that trait. However it feels incorrect for an editor instance to be trying to change a trait on its factory...
Also as I think more about this PR, I am worried about Hyrum's law here. Even if the behavior change seems "more" correct, it is possible that users are dependent on the current behavior.
rahulporuri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a couple of comments.
Can you update the PR description as well? I think it is outdated as we modified the approach after the first review.
traitsui/qt4/range_editor.py
Outdated
| high = Any() | ||
|
|
||
| #: Formatting string used to format value and labels | ||
| #: Deprecated: This trait is no longer used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you search for users of the format trait on this editor? I'm not even sure how one would go about specifically searching for such uses. Whether or not users exist would help us decide on whether or not we need to convert format into a property as well - and make getting/setting format raise warnings as well.
Co-authored-by: Poruri Sai Rahul <[email protected]>
|
I've updated the news fragment, although it is still a "bugfix". It really sort of belongs in "deprecation" as well... Should I include it in both (ie add another news fragment with the same message just tagged as deprecation perhaps? |
|
CI is failing on ubuntu-latest with pyside2:
I have a suspicion that these failures occur when we have CI running for multiple PRs at the same time. This is really a hunch, but with some quick googling I have seen some discussions about |
This comment has been minimized.
This comment has been minimized.
rahulporuri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still LGTM
|
@aaronayres35 can you update the PR description because it feels outdated |
closes #1650
This PR adds support for
format_funcfor theRangeEditor. It does so by calling thestring_valuemethod defined on the factory, rather than justself.format % _____. See method definition here:traitsui/traitsui/editor_factory.py
Lines 190 to 208 in e2521b4
I am just realizing while opening this that although the base
EditorFactoryclass defines aformat_strtrait, theRangeEditordefines its ownformattrait to hold the format string instead.I suspect this will cause problems, hence the WIP for now. I would like to renameformattoformat_strbut that is part of the public api...Perhaps I will need to redefine thestring_valuemethod onRangeEditorand have it be exactly the same as the base class just replacingformat_strwithformat... 🤔~EDIT: I went with the approach mentioned of "redefine the
string_valuemethod onRangeEditor...". It smells a bit, but seems necessary (?) I am not sure why RangeEditor chose to use its own trait there previously rather than usingformat_str. ~This PR also went on to deprecate the
formattrait on theRangeEditorEditorFactoryand also on the toolkit specificEditorimplementations. Users should transition to usingformat_strandformat_funcon the editor factory. Theformattrait will be removed in traitsui 8.0 (see #1704)Checklist