Skip to content
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

Sweep of Python 2 compatibility features #801

Closed
drvinceknight opened this issue Jan 1, 2017 · 17 comments
Closed

Sweep of Python 2 compatibility features #801

drvinceknight opened this issue Jan 1, 2017 · 17 comments

Comments

@drvinceknight
Copy link
Member

There are various things in the library that can now be simplified as we no longer support py 2.

For example various computations had to be explicitly done as float division. These can be removed now :)

@rkty13
Copy link
Contributor

rkty13 commented Jan 7, 2017

Hi! I'm pretty new to open source projects even though I've been programming for a while now. I'm interested in contributing to this project and I thought this issue might be a good place to start. Do you have any suggestions for how I should tackle this?

@drvinceknight
Copy link
Member Author

Hi! I'm pretty new to open source projects even though I've been programming for a while now. I'm interested in contributing to this project and I thought this issue might be a good place to start. Do you have any suggestions for how I should tackle this?

Hi @rkty13! Welcome!

I think this issue would be a good place to start indeed :)

To give a bit of background (and apologies if this is all known), this library used to support python 2 but now only supports python 3. In the past, to ensure compatibility we had to do certain little things that aren't needed anymore. For example, in python 2, division was always integer division so 5/2 would give 2, to ensure that we always got floats when we wanted to we had a lot of things like float(5) / 2 which gives 2.5 in both python 2 and 3.

So this issue is to refactor/clean up code to get rid of all the extra things we were doing to ensure the library worked fine with python 2. The idea is to simply go through the source code and remove them. For example in axelrod/result_set.py you can see this line https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/result_set.py#L357:

                counters.append(Counter({key: float(value) / total for
                                         key, value in counter.items()}))

That can be replaced with:

                counters.append(Counter({key: value / total for
                                         key, value in counter.items()}))

So you could simply remove that and all the tests should still pass (there's information on running the tests here: http://axelrod.readthedocs.io/en/latest/tutorials/contributing/strategy/running_tests.html).

That's just one example where I'm talking about float division but there will be other little things here and there (including in the strategy files: axelrod/strategies/*py).

I hope that's helpful, but don't hesitate to ask if not. You can usually get one of us on the gitter channel if you want to have a quick chat: https://gitter.im/Axelrod-Python/Axelrod We take pride in being helpful to newcomers (to programmer and/or open source) so please let us know how we can help :)

The full documentation might also be helpful: http://axelrod.readthedocs.io/en/latest/tutorials/contributing/index.html

@rkty13
Copy link
Contributor

rkty13 commented Jan 8, 2017

Thank you for the pointer! I guess what I really meant to ask though was if I should do this all in a new branch in this repo or if I should fork the project first and then submit a pull request. Sorry about the confusion!

@marcharper
Copy link
Member

In a fork is best, since you probably can't push to this repository.

@rkty13
Copy link
Contributor

rkty13 commented Jan 9, 2017

Thank you, I'll get started on that now!

@rkty13
Copy link
Contributor

rkty13 commented Jan 11, 2017

For calling the methods of a superclass, which would be the best way to do so for Python 3?

In https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/match_generator.py#L224 this is written:

super(SpatialMatches, self).__init__(players, turns, game, repetitions, noise)

However, in the same file (https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/match_generator.py#L263), this is written:

ProbEndRoundRobinMatches.__init__(self, players, prob_end,
                                          game, repetitions, noise)

which makes use of old-style classes from Python 2.

From the Python 3 docs, super() with zero arguments can also be used to reference the superclass. If I were to rewrite the first example, it would look like this:

super().__init__(players, turns, game, repetitions, noise)

Should I only change the method calls using old-style classes, or should I change everything to have a consistent form?

@marcharper
Copy link
Member

My vote would be to change them all to the preferred py3 format.

@rkty13
Copy link
Contributor

rkty13 commented Jan 11, 2017

By that do you mean the zero arguments format?

@marcharper
Copy link
Member

Yep.

@rkty13
Copy link
Contributor

rkty13 commented Jan 15, 2017

In https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/random_.py, there are two functions called random_choice() and randrange() that are used because of inconsistencies between Python 2's and 3's implementation of random.choice() and random.randrange(), respectively.

However, when I try replacing, for example, the randrange() function with Python 3's standard random.randrange(), a few tests begin to fail because of it. Is there a way I should go about fixing this issue, or is it something that should be left alone for now?

@marcharper
Copy link
Member

The typical reason for these tests is to make sure that all the possible behaviors for stochastic strategies are seen, so ideally we'd find a new random seed in each case that makes the test pass.

There may be a few tests that this is difficult to do for so we may want to substitute a different test. If there are some tricky cases just skip them for now and we'll decide how best to fix them on a case by case basis. A separate PR for this specific py2->3 change is probably a good idea.

@rkty13
Copy link
Contributor

rkty13 commented Jan 16, 2017

Most of the changes have been made in #818. Some things I could not change:

Overall I think I have caught most of the differences between Python 2 and Python 3.

@drvinceknight
Copy link
Member Author

Thanks @rkty13!

Dropping the use of random_choice() and randrange() in https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/random_.py as noted in #801.
Due to Multiple Inheritance, it is preferred to use the old-style superclass/direct reference in https://github.com/Axelrod-Python/Axelrod/blob/master/axelrod/match_generator.py#L263.

I suggest we close this issue and potentially open issues for those two remaining points?

@marcharper
Copy link
Member

It's really just one issue though right? There's not much we can do about the second one.

@drvinceknight
Copy link
Member Author

Yup!

And actually I'm not sure we do want to get rid of random_choice that's now doing more than just being py2 compatible but also ensuring the random state is not modified for deterministic p. I think that just needs the docstring to be fixed (it's not actually correct now: it doesn't emulate random.choice).

@marcharper
Copy link
Member

+1 let's close and leave random_choice as is.

@drvinceknight
Copy link
Member Author

Have opened #826 which tweaks the docstring for random_choice. Merging that will close this issue.

janga1997 pushed a commit to janga1997/Axelrod that referenced this issue Jan 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants