-
Notifications
You must be signed in to change notification settings - Fork 53
Add python 2 and 3 support #280
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
In python 2, calling just `.items()`, `.values()`, or `.keys()` returns a copy of dictionaries list of key-value pairs, values, or keys, respectively. This results in extra memory overhead when used to iterate over a dictionary and instead it was common to use the `.iteritems()` methods to generate an iterator. In python 3, `.items()` now returns an iterator-view, and the `iteritems()` method has been removed. Because python 3 is the current target, using `.items()` and taking the memory hit in python 2 is preferable over using ifs or packages like six to provide efficient iteration across both python 2 and 3.
@jhkennedy, this is great!!! I'm going through the commits one at a time. I'll note a few things here as I do because inline comments are mostly just confusing. |
Regarding commit 7a474d1, I think there are at least 3 more |
# this is an array of date strings like 'xtime' | ||
# convert to string | ||
timeStrings = [''.join(xtime).strip() for xtime in timeVar.values] | ||
timeStrings = [''.join(xtime.astype('U')) for xtime in timeVar.values] |
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.
@jhkennedy, I don't think the .strip()
should have been lost here. The xtime
variable typically has trailing white space.
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.
Ah, blast. That's why I was having problems in timekeeping. 😧
I agree, this should be there still.
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 the only thing I haven't fixed because I didn't want to edit your commit history. Once it's fixed, I'll run a few more tests but everything looks good to me so far.
|
||
# change underscores to spaces so both can be supported | ||
dateString = dateString.replace('_', ' ') | ||
dateString = dateString.replace('_', ' ').strip() |
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 fine, but I think the .strip()
was previously in the calling code and you deleted it by mistake. Definitely doesn't hurt if this function handles dates with extra whitespace.
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 need to test this with some actual data but so far it looks really promising. Just a few very small changes I've seen so far.
...and yet you get a giant red x from me suggesting you screwed something up. Thanks, GitHub, for making me look like a jerk. |
One other thing, our workflow is typically to work on our own forks of MPAS-Analysis rather than in branches within MPAS-Dev/MPAS-Analysis. I don't think this matters much. I personally just prefer it because it keeps the main repo free of clutter and it allows anyone who wants to to contribute without needing write access to the main repo. |
Xylar Asay-Davis | ||
''' | ||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals |
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.
These lines are all too long (more than 80 characters) to be PEP8 compliant. Could they be broken into multiple lines, please?
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 do! Are you trying to follow PEP8 exactly? I've got lots of warnings for variable naming capitalization so I turned off the PEP8 checks.
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 taken care of these already, so no need to change them again.
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.
We're trying to follow PEP8 pretty closely but we use mixed case for variable names. This doesn't give me any trouble in spyder but I guess other checkers might be stricter about that particular issue.
We definitely allow longer lines when it doesn't make sense to break them but this would be a case where I would break up lines.
Okay, I went ahead and pushed some commits that were needed in order for my python 2.7 test to run successfully. These address all of my comments above except the missing |
@jhkennedy, I don't think we're too worried about having every single commit work, so I don't think there's a need to squash commits later on. It could be useful to see the process here because we'll need to recreate it for other outstanding branches that have yet to be merged. |
mpas_analysis/ocean/index_nino34.py
Outdated
|
||
nt = len(inputData) | ||
sp = (len(wgts) - 1)/2 | ||
sp = int((len(wgts) - 1)/2) |
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.
It's probably better to use integer division here instead of a type cast:
sp = (len(wgts) - 1) // 2
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.
Okay, agreed. I'll edit that commit, then. In which case, I'm not done after all...
I'm about to mess with commit history so probably best not to do any committing just now. I've got tests working in both python2 and python3, so we're making rapid progress! |
00c1e14
to
180289c
Compare
Okay, done with messing with the commit history. @jhkennedy, feel free to modify/add commits as you see fit. |
180289c
to
836b39a
Compare
@pwolfram, is this something you're going to have time to review? |
In python 3, stdout/stderr are bytes objects, which get logged incorrectly unless they get decoded into strings.
Must be decoded back to a unicode string before being written out.
836b39a
to
89666c4
Compare
It actually might be better to just stylistically pick absolute imports instead of relative imports (following the pythonism "explicit is better than implicit").
Oh right, my bad! I actually prefer the forking workflow as well. |
I can't honestly say why we use relative imports. I guess I just learned that way by following examples I found. @pwolfram, was this an explicit choice you made for some reason early on? Or were you following my lead? |
In any case, I would say a switch to absolute imports would be fine, but we should do it as a separate clean-up PR. |
ff7d315
to
fb9d482
Compare
Travis will now test python 2.7, 3.5, and 3.6.
fb9d482
to
58bd2da
Compare
Awesome! It looks like CI is working, too. We're still waiting on 3.6 but it would be a surprise to me if 3.5 worked and 3.6 didn't. |
I actually had to do a fixup just a little bit ago because 3.5 didn't work, but 3.6 did (forgot to use the conda-forge channel when creating the env). Looks like they are all working now! |
TestingI've successfully run:
Links to the output are above. |
@pwolfram, unless you think you'll have time to review this today or tomorrow, I think I'm going to take you off as a reviewer and go ahead and merge this PR. Please let me know one way or another. |
@jhkennedy, if you are happy with the PR now, I'd suggest taking off the "don't merge" tag. You can merge it yourself if you like (once we've heard from @pwolfram) or I'll do it, whichever you prefer. |
I just went through the output you linked, and it looks like we're ready to merge. |
I'm happy to merge it; do you want me to leave the branch for easy python 2 -> 2+3 reference for a while? |
No, go ahead and delete the branch when you merge. It's easy enough to go back through the commit history as needed, especially because the commit names can give you at least a pretty good idea of what's in there. |
This adds python 2 and 3 support using the module `six` (as little as possible). The code base now follows python 3 styling with the use of __future__ imports for compatibility. This means: * print is a function call instead of a statement * Strings will typically be unicode instead of byte strings now. * imports need to explicitly declare relative imports * .keys()/.items()/.values() are used instead of iter versions from python 2 (there will be more memory overhead when running in python 2) * Some imports like ConfigParser will need to be handled by six while python 2 is being supported. Travis-CI will now run the pytests for python 2.7, 3.5, and 3.6.
This PR adds python 2 and 3 support using the module
six
as little as possible.I've tried to commit like-changes in small chunks so you can easily see what was needed to change the code. Note: that means that all commits from 57dbcb9 to cb5e801 are broken. This could all be squashed for merging into master.
Status:
All tests pass in both python 2.7 and 3.5, but there are likely issues lurking in the python 2 code now with unicode vs byte strings.
Left to do:
configure ci for tox (see Addition of automatic continuous integration (CI) #40 and Adds travis continuous integration (CI) for pytest #42)
check all usages of
str
for cross compatibilityfixes #43