Skip to content

Update physical type implementation#11625

Merged
mhvk merged 14 commits into
astropy:mainfrom
namurphy:physical-type-updates
Apr 29, 2021
Merged

Update physical type implementation#11625
mhvk merged 14 commits into
astropy:mainfrom
namurphy:physical-type-updates

Conversation

@namurphy

@namurphy namurphy commented Apr 22, 2021

Copy link
Copy Markdown
Contributor

Description

This pull request is to clean up the implementation of PhysicalType in a few places. The changes I'm planning to make are:

The changes to __str__ would affect #11618, or perhaps be made in #11618 instead.

EDIT: This is a follow-up of #11204 , fix #11617

@github-actions github-actions Bot added the units label Apr 22, 2021
@github-actions

Copy link
Copy Markdown
Contributor

👋 Thank you for your draft pull request! Do you know that you can use [ci skip] or [skip ci] in your commit messages to skip running continuous integration tests until you are ready?

Comment thread astropy/units/physical.py Outdated
namurphy and others added 5 commits April 25, 2021 13:17
- Added 'velocity' as a physical type name along with 'speed'
- Removed 'sustained displacement' from 'absement' because the former
  is more like a definition than a name
Because the physical_type attribute of a unit was a str before astropy#11204,
there may be code that depends on those str methods for the physical_type
attribute. This approach was adapted from code suggested in astropy#11204 after
it was merged.

Co-authored-by: Marten van Kerkwijk <mhvk@astro.utoronto.ca>
I made it return 'energy density, pressure, stress' rather than using set
notation.  I tentatively chose commas rather than slashes for readability.
@namurphy namurphy force-pushed the physical-type-updates branch from 5287364 to a77e1d4 Compare April 25, 2021 17:17
@namurphy namurphy marked this pull request as ready for review April 25, 2021 17:24
Comment thread astropy/units/physical.py Outdated

@nstarman nstarman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Excepting a changelog, LGTM!

Comment thread astropy/units/tests/test_physical.py Outdated
Comment on lines +484 to +491
"method, expected",
[
("title", 'Length'),
("isalpha", True),
("isnumeric", False),
("upper", 'LENGTH')
],
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

black isn't encouraged much in this repo, as it conflicts with existing style some times. The perception might change in the future, so who knows.

@namurphy namurphy Apr 27, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I changed the style a bit in response, but any of the maintainers should please feel free to suggest and accept stylistic changes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The perception might change in the future, so who knows.

I've been itching to do >>> black astropy and git push for years now. 🤣

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No, please, no!!

Comment thread astropy/units/physical.py Outdated
@namurphy

namurphy commented Apr 25, 2021

Copy link
Copy Markdown
Contributor Author

Ready for review! Some questions...

  • When there are multiple physical types names, what should the PhysicalType.__str__ separator character be? Two of the main possibilities are a , or a /. That would give 'speed, velocity' or 'speed/velocity'.

    I chose , for now because it's more readable to me than / when there are physical type names with multiple words, and / makes me think division. The advantage of / is that it would be a valid input for PhysicalType for backwards compatibility, but currently not for get_physical_type which is intended to be one of the two main ways to access physical types.

    If we want to get more readable/fancy, we could even do something more complicated like 'speed or velocity' or 'energy density, pressure, or stress'.

  • Am I handling the deprecation warning appropriately? In particular, I'm not specifying the version of Astropy it'll be removed in.

[slightly edited for clarity]

@nstarman

nstarman commented Apr 25, 2021

Copy link
Copy Markdown
Member
  • When there are multiple physical types names, what should the PhysicalType.__str__ separator character be? Two of the main possibilities are a , or a /. That would give 'speed, velocity' or 'speed/velocity'.
    I chose , for now because it's more readable to me when there are physical type names with multiple words than /, and / makes me think division. The advantage of / is that it would be a valid input for PhysicalType for backwards compatibility, but currently not for get_physical_type which is intended to be one of the two main ways to access physical types.

I prefer "," (but actually not visually). This class is new behavior and it seems reasonable to prioritize get_physical_type.

If we want to get more readable/fancy, we could even do something more complicated like 'speed or velocity' or 'energy density, pressure, or stress'.

Looks nice. But it doesn't feel necessary. I know in formal logic "or" is considered inclusive, but that's not true colloquially. Identifying physical types by their units makes it impossible to differentiate between energy density and pressure, so it feels wrong to use "or". But that's just IMO.

  • Am I handling the deprecation warning appropriately? In particular, I'm not specifying the version of Astropy it'll be removed in.

Do we even want to set a hard deadline? This backwards compatibility is to give affiliate packages time and reason to switch. I think it's better to have this be unspecified, have someone stumble on it in a few years, say "Oh yeah!", and ask around if anyone's still using it. @pllim, you have one such affiliate package. Thoughts?

@namurphy namurphy force-pushed the physical-type-updates branch from 5b22b1b to 96d9230 Compare April 25, 2021 18:40
@nstarman

Copy link
Copy Markdown
Member

@mhvk LGTM

@pllim pllim added this to the v4.3 milestone Apr 26, 2021
@pllim pllim added Affects-dev PRs and issues that do not impact an existing Astropy release no-changelog-entry-needed labels Apr 26, 2021
Comment thread astropy/units/physical.py Outdated
Comment thread astropy/units/tests/test_physical.py Outdated
@pllim

pllim commented Apr 26, 2021

Copy link
Copy Markdown
Member

This deprecation comes a bit too late to the release cycle than I like... Doesn't give downstream maintainers much time to catch up before branching happens. Still, hopefully minor enough that it won't cause too much trouble, and better to get this in before #11204 is released. 🤞

namurphy and others added 3 commits April 26, 2021 18:28
@namurphy

Copy link
Copy Markdown
Contributor Author

This deprecation comes a bit too late to the release cycle than I like...

I had intended to get #11204 finished two months earlier than I did, but pandemic era brain blah got the better of me...

Still, hopefully minor enough that it won't cause too much trouble, and better to get this in before #11204 is released. crossed_fingers

I just did a search of GitHub, and I found only one usage of a string method on a physical_type attribute of a unit before GitHub's search interface started to make my brain hurt. With this PR, PhysicalType should be duck typing previous string behavior pretty well. I hope. 😸

@mhvk mhvk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some small bits, but one slightly larger question for __str__, on what the separator should be.

Comment thread astropy/units/physical.py Outdated
"from PhysicalType instances is deprecated since 4.3 and will be removed in a "
"subsequent release.")
warnings.warn(warning_message, AstropyDeprecationWarning)
self_str_attr = getattr(str(self), attr, None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No need for the ", None" any more if attr in dir(str), right?

Note that personally I'd prefer to stick with keeping this on top - if we enter __getattr__, regular attribute access has failed already so it doesn't really matter if it is slightly slower. And I'm just not 100% sure that dir(str) and hasattr(str(self), attr) are really completely equivalent...

Comment thread astropy/units/physical.py Outdated
self_str_attr = getattr(str(self), attr, None)
return self_str_attr
else:
raise AttributeError(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just do super().__getattribute__(attr) so you get the standard error message.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

🤣. @namurphy, apologies for suggesting otherwise.

Comment thread astropy/units/physical.py Outdated
return self._physical_type_list[0]
else:
return self._name_string_as_ordered_set()
return ", ".join(self._physical_type_list)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we're dropping the braces, should we make this "/".join(...) so that in principle it can be read back?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there any expectation that __str__ can be read back? I thought that's what __repr__ is for

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agreed, just that we accept / on input, so it seems perhaps more logical to re-use that. I also like that it is commonly used to mean "or", while with the , the braces helped to make that clear.

@nstarman nstarman Apr 27, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Clarity and round-tripping are definitely good things. I don't have a strong opinion whether "/" XOR "," is superior as they have a similar set of advantages and disadvantages, depending on use case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It would be worthwhile to have operations like u.Pa.physical_type == str(u.Pa.physical_type) work as expected, so I'll change it to /.

We'd have to do a bit more to make it a full round trip, since the / separated physical types are allowed in def_physical_type and PhysicalType and with operators like ==, but not in get_physical_type. This was necessary for the former three cases since there was a previously a str physical type named "momentum/impulse" and we wanted to maintain backward compatibility, but this wasn't a concern for get_physical_type since it previously returned "momentum/impulse" instead accepting it as an argument. Adding the full round trip is out of scope of this PR but it's something that could be added in later.

@namurphy

Copy link
Copy Markdown
Contributor Author

Closes #11617.

@pllim

pllim commented Apr 28, 2021

Copy link
Copy Markdown
Member

Re: #11625 (comment) -- @namurphy , the auto-close feature only kicks in if you state that in the original post. I have updated the original post for you. FYI.

@mhvk mhvk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks all great to me now! Let's get this in!

@mhvk mhvk merged commit 0cebd7c into astropy:main Apr 29, 2021
@dhomeier

Copy link
Copy Markdown
Contributor

Thanks for providing a more convenient access here. It seems some operations like
if cm_unit.physical_type in ('length', 'frequency'):
still need explicit conversion to str(), or would there be a better alternative?

@nstarman

nstarman commented Jun 23, 2021

Copy link
Copy Markdown
Member

u.cm.physical_type in ('length', 'frequency') returns True for me. (Python 3.9, Mac, Astropy 5.0dev)

It should work because the tuple.__contains__ does equality testing on each element and u.cm.physical_type == 'length' is True because PhysicalType does a string conversion internally.

@dhomeier

Copy link
Copy Markdown
Contributor

OK, that does work on 4.3rc1, and even
u.eV.physical_type in ('length', 'freq', 'energy')
evaluates as True. Thanks!
So it's only the inverse lookup for a partial string
'spectral flux' in u.Jy.physical_type
that needs being taken care of...

@nstarman

Copy link
Copy Markdown
Member

I guess PhysicalType needs to implement __contains__

@mhvk

mhvk commented Jun 23, 2021

Copy link
Copy Markdown
Contributor

I'm -0 on __contains__ - may better for that case let people do 'spectral flux' in str(physical_type)? While adding __contains__ means we would improve backward compatibility, I'm not sure one should aim for matching on substrings generally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Affects-dev PRs and issues that do not impact an existing Astropy release no-changelog-entry-needed units

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make PhysicalType instances support string methods with deprecation warnings

5 participants