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
DM-13222: Add getScalar and getArray methods to PropertySet and PropertyList and prefer them #36
Conversation
@@ -170,8 +205,7 @@ def setstate(self, state): | |||
class PropertySet: | |||
# Mapping of type to method names | |||
_typeMenu = {bool: "Bool", | |||
long: "LongLong", | |||
int: "Int", # overwrites long on Python 3.x | |||
int: "Int", |
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.
Since all Python 3 int
s are potentially very large, should this mapping be
int: "LongLong",
?
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 wondering the same thing. I just copied the old code, which over-wrote the long: "LongLong"
entry in Python 3, leaving the int
entry. But I was surprised the two entries were not swapped so that py3 retained the "LongLong" entry.
I'm wondering if @ktlim has an opinion about this. I'm certainly happy to change it.
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 is not actually used at all now that there's _guessIntegerType()
.
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 should I delete the entry or add a comment explaining that the exact integer type doesn't matter as long as it's some kind of integer, or...?
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'm pretty sure it isn't used at all, so it's best to delete it to make sure it isn't used accidentally.
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.
Thank you. I deleted it with a code comment. The unit tests pass.
"""Extract a single Python value of unknown type""" | ||
"""Get a value of unknown type as a scalar or array | ||
|
||
Return a scalar if there is only one value, else return an array |
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.
Also returns an array if asArray==True
of course.
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 see no evidence that the asArray argument is used by any code in our stack, except two unit tests in daf_base, so I am going to try removing it from PropertySet.get
and PropertyList.get
and see if Jenkins passes. If it does, this will make it much easier to implement shared base code for getArray
and getScalar
since we can change the argument to asScalar
and only return a scalar if that is true.
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.
DM-14770 provides an example of why the asArray
argument may be good to delete. I found code that treats the second argument as a default value, in case the requested item is missing.
if elemType: | ||
return getattr(container, "getArray" + elemType)(name)[-1] | ||
|
||
raise TypeError("Item {} is not numeric or string".format(name)) |
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 think you could return a PropertyList
, PropertySet
, or PersistablePtr
here; they're all scalar in this sense, and that would allow you to fully deprecate get()
.
But, failing that, since these two methods differ only in name and four characters ([-1]
), wouldn't it be better to combine them? Or, even better, if get()
is not to be removed, implement them in terms of get(..., asArray=True)
?
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.
Do you think that just getScalar
should be able to return a PropertyList
, PropertySet
, or PersistablePtr
, or that getArray
should be able to do so as well?
I can see arguments for all 4 options, though I personally only like the first 3:
- neither (the current code):
PropertySet
and the like are neither scalars nor arrays, so usingget
makes for cleaner and less surprising code. Also the user is less likely to be surprised by retrieving aPropertySet
when they expected a number, string or list of either of those. - both: it's simple to return the obvious object if it's not numeric or string-like. It allows the user to iterate over all names and gets something reasonable back. The user just has to be careful with types, but that's implied by a container such as this anyway. Also this allows us to (in theory) deprecate
get
. getScalar
only:getArray
always returns an array andPropertySet
and the like are arguably more like scalars than arrays. Other than that, all the arguments toboth
also apply to this option. I think it would be acceptable, but I worry it might annoy and confuse users to have to remember which ofgetScalar
andgetArray
can returnPropertySet
and which cannot.getArray
only:getArray
returns the most "native" format -- since internally numeric and string data is stored in an array. But that's somewhat of an internal detail, so I consider this a very weak argument. This is by far my least favorite choice, since I think it would be difficult to explain whygetArray
can returnPropertySet
butgetScalar
cannot. I fear many users would be confused and frustrated.
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.
After talking to @ktlim we agreed that getScalar
will be able to return PropertySet
and similar items, but that getArray
will continue to raise. If I am successful in removing the asArray
argument of get
(without breaking existing code) then this will result in a fairly logical API. With the asArray
argument it's a bit weird because get(name, asArray=True)
can return PropertySet
and getArray
cannot.
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.
As expressed in Slack, I'm OK with either "both" or "getScalar only".
@@ -170,8 +205,7 @@ def setstate(self, state): | |||
class PropertySet: | |||
# Mapping of type to method names | |||
_typeMenu = {bool: "Bool", | |||
long: "LongLong", | |||
int: "Int", # overwrites long on Python 3.x | |||
int: "Int", |
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 is not actually used at all now that there's _guessIntegerType()
.
tests/test_PropertyList.py
Outdated
|
||
And check that it raises a DeprecationWarning | ||
""" | ||
with warnings.catch_warnings(record=True) as w: |
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.
Why not:
with self.assertWarns(DeprecationWarning):
do_something()
7b3d260
to
05867bb
Compare
The doc incorrectly stated that it always returned a scalar
to PropertySet and PropertyList. Expand existing unit tests to test them.
and PropertyList.get
using _propertyContainerGet with a new argument that controls whether the returned value is array, scalar or automatically chosen
of PropertySet and PropertyList, including getArray and getScalar
No description provided.