Design Principles

  1. Convert to bytes closest to the perimeter.
  2. Business logic in the code should scream back at you. Have the code be readable, so it is not swimming in details related to string conversions.

Efficiency Tricks

  1. Use Regex replacements whenever possible - and bulk update the entire codebase.  PR 21842 is an example doing this for all assertIn(..response.content) cases.
  2. Since test startup time is slow, run and fix all tests within a file in bulk - rather than one test at a time.

FAQ


QuestionAnswer
1What version of Python 3 should our code work on?

For webservices 3.5, For libraries, 3.5 and 3.6

2How do I indicate that a repo works with Python 3?Make sure that your openedx.yaml file has an up-to-date oeps section that indicates that your repo is OEP-7 compliant.   See here for an example.
3Invalid Syntax ur"regex_string"

The ur raw string goes away in python three.  You can achieve the same effect by wrapping the raw r"regex" string in a six.text_type()


If the string passes in other strings via format be careful to escape the incoming strings as well.  You can use re.escape

to do this before interpolating them into your unicode regex string.

4Sorted with cmp seems to be broken?The cmp argument of sorted goes away in python 3.  You need to change how the sorting is done to be able to generate a sane order using the key function instead.
5response.content is now a bytestring

Option A (when using Django.test): Convert any assertIn(..response.content) and assertNotIn(..response.content) test code to use assertContains and assertNotContains.  See this PR.

Option B (if not using Django.test): Convert string to be a bytestring. Example PR: TODO

6Output of random is inconsistent across Python versions

Option A (when no compatibility issues): Use Python3's random since it results in a better distribution output. As explained in this Python issue, randomization output is not guaranteed to remain the same across Python versions. So our tests (and production code) should not assume consistent randomization, even with the same seed value.

Option B (when compatibility issues exist): If there are any data compatibility issues because of legacy code that assumes randomization consistency, use the random2 library in order to stick with Python2's old implementation. A situation where this might happen is if we're only storing a seed and recompute the state of an XBlock based on that seed using random.choice/shuffle/etc. as happens with Capa problems. See this thread.