-
-
Notifications
You must be signed in to change notification settings - Fork 649
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
Fix test_objects handling of dataclass() py2-py3 compatibility #6098
Conversation
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.
Thanks for figuring this out and fixing this! I distinctly remember using str
in this test file, seeing errors because I didn't realize what unicode literals meant at the time, and being pretty frustrated and having a great deal of trouble understanding what was wrong. It really irked me when not solving this led to annoyances in other places like Snapshot
, which had to do an explicit conversion to str
(which has since been removed). Thanks again for taking another look and fixing the problem.
The only thing I would like to see is a comment in the datatype
docstring which says to use text_type
for string-typed datatype
arguments, because it seems like without looking at this file people who didn't see this PR might just use str
or unicode
and fall into the same issue.
other thoughts:
Now that I'm thinking about it, would it make sense to potentially check for declarations of str
or unicode
-typed fields in datatype()
invocations and raise an error? I don't think that needs to be in the scope of this PR because this is focused on 2/3 compat, but it seems like it would be a waste to solve this problem and then allow users to accidentally use the wrong type. It would also immediately make it easier to spot uses of str
that we may have missed, because those will raise. I think that probably sounds like a job for a followup PR, along with updating the engine README -- but in this PR just noting that text_type
should be used in the docstring (so that we maintain 2/3 compat for future datatype
s people write) would be sufficient and useful.
I also just realized the datatype
docstring needs to be updated anyway to note that we support arbitrary TypeConstraint
s, not just specific types. That doesn't need to be done here, I think.
I was only able to find one instance of this, but ExecuteProcessRequest should be converted to using this too at some point -- that doesn't need to be done here.
Happy to make both of those changes when I get back on Monday! I think the ExecuteProcessRequest should be a separate PR since this only fixes the tests. I can attach the comment and/or assertion in this PR or a separate one. Regarding accepting arbitrary TypeConstraints, we should probably add testing around that. |
Actually I don’t it will be possible to add an assertion for the datatype constructor.
if PY2:
text_type = unicode
else:
text_type = str So I think the documentation will help at least. |
I didn't realize that about There is a little testing around accepting It bothers me a little that we can't have the assertion that we're using |
@cosmicexplorer : That seems like a bit much to add to this PR. I think that the documentation you're suggesting is not datatype specific at all... It's more along the lines of "when writing Python3 compatible code, use If Eric and co are able to make enough progress here and execute the swapover, then those kinds of docs won't even be necessary... so I'd love to see that progress made. |
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.
Ok, that makes a lot of sense. @Eric-Arellano thanks for responding in such depth -- I will work on focusing comments specifically towards the goal of 2/3 compat for these PRs in the future.
@cosmicexplorer thanks likewise! Most of these porting changes are generated automatically and simple, but there have been a couple complex ones throughout the process like this |
### Problem `./pants3 --no-v1 --v2 test testprojects/tests/python/pants/dummies:passing_target` would fail to execute because we hardcoded the PEX we grab to always use Python 2, rather than matching the current interpreter. Even after fixing this, the command would succeed but output the results as a byte string without `\n` rendered properly, due to improper unicode handling. ### Solution Grab the PEX that corresponds to the current interpreter. Also change the `datatype` for some V2 abstractions to `text_type`, rather than `str`. This is because `datatype()` requires the type to _exactly_ match, and the future backport `str` actually is of type `newstr` in Py2 rather than `unicode`. See #6098 for further context on how we support Py2 and Py3 with `datatype()`. ### Result `./pants3 --no-v1 --v2 test testprojects/tests/python/pants/dummies:passing_target` works for both Python 2 and Python 3, including when switching between the two repeatedly. @illicitonion and I discussed over Slack potential concerns with caching and the interpreter not changing properly, but this does not seem to be an issue.
Followup from #6072, which was an incorrect representation of the changes made to metaprogramming with Python 3 port. Part of #6062.
Problem
object.py
'sdatatype()
function expects exactly one type. This poses an issue when we addfrom builtins import str
to files - in Py2, the type will becomenewstr
, whereas in Py3 the type will becomestr
.type(newstr) != type(str)
, even though the behavior is similar, sodatatype()
will raise an exception.We ran into this issue originally with
test_objects.py
. The original solution only fixed the tests, it didn't actually fix the underlying problem, which I realized whenengine/fs.py
starting breaking with PRs that touched it like thebackend/jvm
port.Solution
The solution has two parts:
datatype
, set the parameter tofuture.utils.text_type
, rather thanstr
. This means in Py2 the type will beunicode
and in Py3 the type will bestr
. Both have the same unicode semantics, which is a good thing.dataclass
as its metaclass, wrap the parameter calls withtext_type(x)
. This will callunicode(x)
in Py2 andstr()
in Py3, resulting in the correct type for the class definition from the first step.What this impacts
Anywhere we create a class with
datatype()
that sets a parameter tostr
, we'll have to make this change to both the class definition and all of its instantiations.The biggest example of this is in
engine/fs.py