We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update conditional build to python3
In https://github.com/kivy/python-for-android/pull/1471 we killed crystax for the CI which then means we need to port the conditional build script to `python3` see https://github.com/kivy/python-for-android/blob/3e561b0/ci/rebuild_updated_recipes.py#L12

Currently it fails with:
```
Traceback (most recent call last):
  File "./ci/rebuild_updated_recipes.py", line 99, in <module>
    main()
  File "./ci/rebuild_updated_recipes.py", line 95, in main
    build(target_python, recipes)
  File "./ci/rebuild_updated_recipes.py", line 59, in build
    crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']
  File "/home/user/venv/lib/python2.7/UserDict.py", line 40, in __getitem__
    raise KeyError(key)
KeyError: 'CRYSTAX_NDK_HOME'
```
e.g. https://api.travis-ci.org/v3/job/458635355/log.txt

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ci/constants.py`
Content:
```
1 from enum import Enum
2 
3 
4 class TargetPython(Enum):
5     python2 = 0
6     python3crystax = 1
7 
8 
9 # recipes that currently break the build
10 # a recipe could be broken for a target Python and not for the other,
11 # hence we're maintaining one list per Python target
12 BROKEN_RECIPES_PYTHON2 = set([
13     # pythonhelpers.h:12:18: fatal error: string: No such file or directory
14     'atom',
15     # https://github.com/kivy/python-for-android/issues/550
16     'audiostream',
17     'brokenrecipe',
18     # https://github.com/kivy/python-for-android/issues/1409
19     'enaml',
20     'evdev',
21     # distutils.errors.DistutilsError
22     # Could not find suitable distribution for Requirement.parse('cython')
23     'ffpyplayer',
24     'flask',
25     'groestlcoin_hash',
26     'hostpython3crystax',
27     # https://github.com/kivy/python-for-android/issues/1398
28     'ifaddrs',
29     # https://github.com/kivy/python-for-android/issues/1354
30     'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',
31     'kiwisolver',
32     # https://github.com/kivy/python-for-android/issues/1399
33     'libglob',
34     'libmysqlclient',
35     'libsecp256k1',
36     'libtribler',
37     'ndghttpsclient',
38     'm2crypto',
39     'netifaces',
40     'Pillow',
41     # depends on cffi that still seems to have compilation issues
42     'protobuf_cpp',
43     'xeddsa',
44     'x3dh',
45     'pynacl',
46     'doubleratchet',
47     'omemo',
48     'cryptography',
49     # https://github.com/kivy/python-for-android/issues/1405
50     'psycopg2',
51     'pygame',
52     # most likely some setup in the Docker container, because it works in host
53     'pyjnius', 'pyopenal',
54     'pyproj',
55     'pysdl2',
56     'pyzmq',
57     'secp256k1',
58     'shapely',
59     'twisted',
60     'vlc',
61     'websocket-client',
62     'zeroconf',
63     'zope',
64 ])
65 BROKEN_RECIPES_PYTHON3_CRYSTAX = set([
66     'brokenrecipe',
67     # enum34 is not compatible with Python 3.6 standard library
68     # https://stackoverflow.com/a/45716067/185510
69     'enum34',
70     # https://github.com/kivy/python-for-android/issues/1398
71     'ifaddrs',
72     # https://github.com/kivy/python-for-android/issues/1399
73     'libglob',
74     # cannot find -lcrystax
75     'cffi', 'pycryptodome', 'pymuk', 'secp256k1',
76     # https://github.com/kivy/python-for-android/issues/1404
77     'cryptography',
78     # https://github.com/kivy/python-for-android/issues/1294
79     'ffmpeg', 'ffpyplayer',
80     # https://github.com/kivy/python-for-android/pull/1307 ?
81     'gevent',
82     'icu',
83     # https://github.com/kivy/python-for-android/issues/1354
84     'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',
85     # https://github.com/kivy/python-for-android/issues/1405
86     'libpq', 'psycopg2',
87     'netifaces',
88     # https://github.com/kivy/python-for-android/issues/1315 ?
89     'opencv',
90     'protobuf_cpp',
91     # most likely some setup in the Docker container, because it works in host
92     'pyjnius', 'pyopenal',
93     # SyntaxError: invalid syntax (Python2)
94     'storm',
95     'vlc',
96 ])
97 BROKEN_RECIPES = {
98     TargetPython.python2: BROKEN_RECIPES_PYTHON2,
99     TargetPython.python3crystax: BROKEN_RECIPES_PYTHON3_CRYSTAX,
100 }
101 # recipes that were already built will be skipped
102 CORE_RECIPES = set([
103     'pyjnius', 'kivy', 'openssl', 'requests', 'sqlite3', 'setuptools',
104     'numpy', 'android', 'python2', 'python3',
105 ])
106
```

Path: `ci/rebuild_updated_recipes.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """
4 Continuous Integration helper script.
5 Automatically detects recipes modified in a changeset (compares with master)
6 and recompiles them.
7 
8 To run locally, set the environment variables before running:
9 ```
10 ANDROID_SDK_HOME=~/.buildozer/android/platform/android-sdk-20
11 ANDROID_NDK_HOME=~/.buildozer/android/platform/android-ndk-r9c
12 CRYSTAX_NDK_HOME=~/.buildozer/crystax-ndk
13 ./ci/rebuild_update_recipes.py
14 ```
15 
16 Current limitations:
17 - will fail on conflicting requirements
18   e.g. https://travis-ci.org/AndreMiras/python-for-android/builds/438840800
19   the list of recipes was huge and result was:
20   [ERROR]:   Didn't find any valid dependency graphs.
21   [ERROR]:   This means that some of your requirements pull in conflicting dependencies.
22 - only rebuilds on sdl2 bootstrap
23 - supports mainly python3crystax with fallback to python2, but no python3 support
24 """
25 import sh
26 import os
27 from pythonforandroid.build import Context
28 from pythonforandroid.graph import get_recipe_order_and_bootstrap
29 from pythonforandroid.toolchain import current_directory
30 from ci.constants import TargetPython, CORE_RECIPES, BROKEN_RECIPES
31 
32 
33 def modified_recipes(branch='origin/master'):
34     """
35     Returns a set of modified recipes between the current branch and the one
36     in param.
37     """
38     # using the contrib version on purpose rather than sh.git, since it comes
39     # with a bunch of fixes, e.g. disabled TTY, see:
40     # https://stackoverflow.com/a/20128598/185510
41     git_diff = sh.contrib.git.diff('--name-only', branch)
42     recipes = set()
43     for file_path in git_diff:
44         if 'pythonforandroid/recipes/' in file_path:
45             recipe = file_path.split('/')[2]
46             recipes.add(recipe)
47     return recipes
48 
49 
50 def build(target_python, requirements):
51     """
52     Builds an APK given a target Python and a set of requirements.
53     """
54     if not requirements:
55         return
56     testapp = 'setup_testapp_python2.py'
57     android_sdk_home = os.environ['ANDROID_SDK_HOME']
58     android_ndk_home = os.environ['ANDROID_NDK_HOME']
59     crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']
60     if target_python == TargetPython.python3crystax:
61         android_ndk_home = crystax_ndk_home
62         testapp = 'setup_testapp_python3.py'
63     requirements.add(target_python.name)
64     requirements = ','.join(requirements)
65     print('requirements:', requirements)
66     with current_directory('testapps/'):
67         try:
68             for line in sh.python(
69                     testapp, 'apk', '--sdk-dir', android_sdk_home,
70                     '--ndk-dir', android_ndk_home, '--bootstrap', 'sdl2', '--requirements',
71                     requirements, _err_to_out=True, _iter=True):
72                 print(line)
73         except sh.ErrorReturnCode as e:
74             raise
75 
76 
77 def main():
78     target_python = TargetPython.python3crystax
79     recipes = modified_recipes()
80     print('recipes modified:', recipes)
81     recipes -= CORE_RECIPES
82     print('recipes to build:', recipes)
83     context = Context()
84     build_order, python_modules, bs = get_recipe_order_and_bootstrap(
85         context, recipes, None)
86     # fallback to python2 if default target is not compatible
87     if target_python.name not in build_order:
88         print('incompatible with {}'.format(target_python.name))
89         target_python = TargetPython.python2
90         print('falling back to {}'.format(target_python.name))
91     # removing the known broken recipe for the given target
92     broken_recipes = BROKEN_RECIPES[target_python]
93     recipes -= broken_recipes
94     print('recipes to build (no broken):', recipes)
95     build(target_python, recipes)
96 
97 
98 if __name__ == '__main__':
99     main()
100
```

Path: `pythonforandroid/recipes/jedi/__init__.py`
Content:
```
1 
2 from pythonforandroid.recipe import PythonRecipe
3 
4 
5 class JediRecipe(PythonRecipe):
6     # version = 'master'
7     version = 'v0.9.0'
8     url = 'https://github.com/davidhalter/jedi/archive/{version}.tar.gz'
9 
10     depends = [('python2', 'python3crystax')]
11 
12     patches = ['fix_MergedNamesDict_get.patch']
13     # This apparently should be fixed in jedi 0.10 (not released to
14     # pypi yet), but it still occurs on Android, I could not reproduce
15     # on desktop.
16 
17     call_hostpython_via_targetpython = False
18 
19 
20 recipe = JediRecipe()
21
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ci/constants.py b/ci/constants.py
--- a/ci/constants.py
+++ b/ci/constants.py
@@ -4,6 +4,7 @@
 class TargetPython(Enum):
     python2 = 0
     python3crystax = 1
+    python3 = 2
 
 
 # recipes that currently break the build
@@ -94,9 +95,14 @@
     'storm',
     'vlc',
 ])
+# to be created via https://github.com/kivy/python-for-android/issues/1514
+BROKEN_RECIPES_PYTHON3 = set([
+])
+
 BROKEN_RECIPES = {
     TargetPython.python2: BROKEN_RECIPES_PYTHON2,
     TargetPython.python3crystax: BROKEN_RECIPES_PYTHON3_CRYSTAX,
+    TargetPython.python3: BROKEN_RECIPES_PYTHON3,
 }
 # recipes that were already built will be skipped
 CORE_RECIPES = set([
diff --git a/ci/rebuild_updated_recipes.py b/ci/rebuild_updated_recipes.py
--- a/ci/rebuild_updated_recipes.py
+++ b/ci/rebuild_updated_recipes.py
@@ -9,7 +9,6 @@
 ```
 ANDROID_SDK_HOME=~/.buildozer/android/platform/android-sdk-20
 ANDROID_NDK_HOME=~/.buildozer/android/platform/android-ndk-r9c
-CRYSTAX_NDK_HOME=~/.buildozer/crystax-ndk
 ./ci/rebuild_update_recipes.py
 ```
 
@@ -20,7 +19,7 @@
   [ERROR]:   Didn't find any valid dependency graphs.
   [ERROR]:   This means that some of your requirements pull in conflicting dependencies.
 - only rebuilds on sdl2 bootstrap
-- supports mainly python3crystax with fallback to python2, but no python3 support
+- supports mainly python3 with fallback to python2
 """
 import sh
 import os
@@ -56,9 +55,7 @@
     testapp = 'setup_testapp_python2.py'
     android_sdk_home = os.environ['ANDROID_SDK_HOME']
     android_ndk_home = os.environ['ANDROID_NDK_HOME']
-    crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']
-    if target_python == TargetPython.python3crystax:
-        android_ndk_home = crystax_ndk_home
+    if target_python == TargetPython.python3:
         testapp = 'setup_testapp_python3.py'
     requirements.add(target_python.name)
     requirements = ','.join(requirements)
@@ -75,7 +72,7 @@
 
 
 def main():
-    target_python = TargetPython.python3crystax
+    target_python = TargetPython.python3
     recipes = modified_recipes()
     print('recipes modified:', recipes)
     recipes -= CORE_RECIPES
diff --git a/pythonforandroid/recipes/jedi/__init__.py b/pythonforandroid/recipes/jedi/__init__.py
--- a/pythonforandroid/recipes/jedi/__init__.py
+++ b/pythonforandroid/recipes/jedi/__init__.py
@@ -1,13 +1,11 @@
-
 from pythonforandroid.recipe import PythonRecipe
 
 
 class JediRecipe(PythonRecipe):
-    # version = 'master'
     version = 'v0.9.0'
     url = 'https://github.com/davidhalter/jedi/archive/{version}.tar.gz'
 
-    depends = [('python2', 'python3crystax')]
+    depends = [('python2', 'python3crystax', 'python3')]
 
     patches = ['fix_MergedNamesDict_get.patch']
     # This apparently should be fixed in jedi 0.10 (not released to

{"golden_diff": "diff --git a/ci/constants.py b/ci/constants.py\n--- a/ci/constants.py\n+++ b/ci/constants.py\n@@ -4,6 +4,7 @@\n class TargetPython(Enum):\n     python2 = 0\n     python3crystax = 1\n+    python3 = 2\n \n \n # recipes that currently break the build\n@@ -94,9 +95,14 @@\n     'storm',\n     'vlc',\n ])\n+# to be created via https://github.com/kivy/python-for-android/issues/1514\n+BROKEN_RECIPES_PYTHON3 = set([\n+])\n+\n BROKEN_RECIPES = {\n     TargetPython.python2: BROKEN_RECIPES_PYTHON2,\n     TargetPython.python3crystax: BROKEN_RECIPES_PYTHON3_CRYSTAX,\n+    TargetPython.python3: BROKEN_RECIPES_PYTHON3,\n }\n # recipes that were already built will be skipped\n CORE_RECIPES = set([\ndiff --git a/ci/rebuild_updated_recipes.py b/ci/rebuild_updated_recipes.py\n--- a/ci/rebuild_updated_recipes.py\n+++ b/ci/rebuild_updated_recipes.py\n@@ -9,7 +9,6 @@\n ```\n ANDROID_SDK_HOME=~/.buildozer/android/platform/android-sdk-20\n ANDROID_NDK_HOME=~/.buildozer/android/platform/android-ndk-r9c\n-CRYSTAX_NDK_HOME=~/.buildozer/crystax-ndk\n ./ci/rebuild_update_recipes.py\n ```\n \n@@ -20,7 +19,7 @@\n   [ERROR]:   Didn't find any valid dependency graphs.\n   [ERROR]:   This means that some of your requirements pull in conflicting dependencies.\n - only rebuilds on sdl2 bootstrap\n-- supports mainly python3crystax with fallback to python2, but no python3 support\n+- supports mainly python3 with fallback to python2\n \"\"\"\n import sh\n import os\n@@ -56,9 +55,7 @@\n     testapp = 'setup_testapp_python2.py'\n     android_sdk_home = os.environ['ANDROID_SDK_HOME']\n     android_ndk_home = os.environ['ANDROID_NDK_HOME']\n-    crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']\n-    if target_python == TargetPython.python3crystax:\n-        android_ndk_home = crystax_ndk_home\n+    if target_python == TargetPython.python3:\n         testapp = 'setup_testapp_python3.py'\n     requirements.add(target_python.name)\n     requirements = ','.join(requirements)\n@@ -75,7 +72,7 @@\n \n \n def main():\n-    target_python = TargetPython.python3crystax\n+    target_python = TargetPython.python3\n     recipes = modified_recipes()\n     print('recipes modified:', recipes)\n     recipes -= CORE_RECIPES\ndiff --git a/pythonforandroid/recipes/jedi/__init__.py b/pythonforandroid/recipes/jedi/__init__.py\n--- a/pythonforandroid/recipes/jedi/__init__.py\n+++ b/pythonforandroid/recipes/jedi/__init__.py\n@@ -1,13 +1,11 @@\n-\n from pythonforandroid.recipe import PythonRecipe\n \n \n class JediRecipe(PythonRecipe):\n-    # version = 'master'\n     version = 'v0.9.0'\n     url = 'https://github.com/davidhalter/jedi/archive/{version}.tar.gz'\n \n-    depends = [('python2', 'python3crystax')]\n+    depends = [('python2', 'python3crystax', 'python3')]\n \n     patches = ['fix_MergedNamesDict_get.patch']\n     # This apparently should be fixed in jedi 0.10 (not released to\n", "issue": "Update conditional build to python3\nIn https://github.com/kivy/python-for-android/pull/1471 we killed crystax for the CI which then means we need to port the conditional build script to `python3` see https://github.com/kivy/python-for-android/blob/3e561b0/ci/rebuild_updated_recipes.py#L12\r\n\r\nCurrently it fails with:\r\n```\r\nTraceback (most recent call last):\r\n  File \"./ci/rebuild_updated_recipes.py\", line 99, in <module>\r\n    main()\r\n  File \"./ci/rebuild_updated_recipes.py\", line 95, in main\r\n    build(target_python, recipes)\r\n  File \"./ci/rebuild_updated_recipes.py\", line 59, in build\r\n    crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']\r\n  File \"/home/user/venv/lib/python2.7/UserDict.py\", line 40, in __getitem__\r\n    raise KeyError(key)\r\nKeyError: 'CRYSTAX_NDK_HOME'\r\n```\r\ne.g. https://api.travis-ci.org/v3/job/458635355/log.txt\n", "before_files": [{"content": "from enum import Enum\n\n\nclass TargetPython(Enum):\n    python2 = 0\n    python3crystax = 1\n\n\n# recipes that currently break the build\n# a recipe could be broken for a target Python and not for the other,\n# hence we're maintaining one list per Python target\nBROKEN_RECIPES_PYTHON2 = set([\n    # pythonhelpers.h:12:18: fatal error: string: No such file or directory\n    'atom',\n    # https://github.com/kivy/python-for-android/issues/550\n    'audiostream',\n    'brokenrecipe',\n    # https://github.com/kivy/python-for-android/issues/1409\n    'enaml',\n    'evdev',\n    # distutils.errors.DistutilsError\n    # Could not find suitable distribution for Requirement.parse('cython')\n    'ffpyplayer',\n    'flask',\n    'groestlcoin_hash',\n    'hostpython3crystax',\n    # https://github.com/kivy/python-for-android/issues/1398\n    'ifaddrs',\n    # https://github.com/kivy/python-for-android/issues/1354\n    'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',\n    'kiwisolver',\n    # https://github.com/kivy/python-for-android/issues/1399\n    'libglob',\n    'libmysqlclient',\n    'libsecp256k1',\n    'libtribler',\n    'ndghttpsclient',\n    'm2crypto',\n    'netifaces',\n    'Pillow',\n    # depends on cffi that still seems to have compilation issues\n    'protobuf_cpp',\n    'xeddsa',\n    'x3dh',\n    'pynacl',\n    'doubleratchet',\n    'omemo',\n    'cryptography',\n    # https://github.com/kivy/python-for-android/issues/1405\n    'psycopg2',\n    'pygame',\n    # most likely some setup in the Docker container, because it works in host\n    'pyjnius', 'pyopenal',\n    'pyproj',\n    'pysdl2',\n    'pyzmq',\n    'secp256k1',\n    'shapely',\n    'twisted',\n    'vlc',\n    'websocket-client',\n    'zeroconf',\n    'zope',\n])\nBROKEN_RECIPES_PYTHON3_CRYSTAX = set([\n    'brokenrecipe',\n    # enum34 is not compatible with Python 3.6 standard library\n    # https://stackoverflow.com/a/45716067/185510\n    'enum34',\n    # https://github.com/kivy/python-for-android/issues/1398\n    'ifaddrs',\n    # https://github.com/kivy/python-for-android/issues/1399\n    'libglob',\n    # cannot find -lcrystax\n    'cffi', 'pycryptodome', 'pymuk', 'secp256k1',\n    # https://github.com/kivy/python-for-android/issues/1404\n    'cryptography',\n    # https://github.com/kivy/python-for-android/issues/1294\n    'ffmpeg', 'ffpyplayer',\n    # https://github.com/kivy/python-for-android/pull/1307 ?\n    'gevent',\n    'icu',\n    # https://github.com/kivy/python-for-android/issues/1354\n    'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',\n    # https://github.com/kivy/python-for-android/issues/1405\n    'libpq', 'psycopg2',\n    'netifaces',\n    # https://github.com/kivy/python-for-android/issues/1315 ?\n    'opencv',\n    'protobuf_cpp',\n    # most likely some setup in the Docker container, because it works in host\n    'pyjnius', 'pyopenal',\n    # SyntaxError: invalid syntax (Python2)\n    'storm',\n    'vlc',\n])\nBROKEN_RECIPES = {\n    TargetPython.python2: BROKEN_RECIPES_PYTHON2,\n    TargetPython.python3crystax: BROKEN_RECIPES_PYTHON3_CRYSTAX,\n}\n# recipes that were already built will be skipped\nCORE_RECIPES = set([\n    'pyjnius', 'kivy', 'openssl', 'requests', 'sqlite3', 'setuptools',\n    'numpy', 'android', 'python2', 'python3',\n])\n", "path": "ci/constants.py"}, {"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nContinuous Integration helper script.\nAutomatically detects recipes modified in a changeset (compares with master)\nand recompiles them.\n\nTo run locally, set the environment variables before running:\n```\nANDROID_SDK_HOME=~/.buildozer/android/platform/android-sdk-20\nANDROID_NDK_HOME=~/.buildozer/android/platform/android-ndk-r9c\nCRYSTAX_NDK_HOME=~/.buildozer/crystax-ndk\n./ci/rebuild_update_recipes.py\n```\n\nCurrent limitations:\n- will fail on conflicting requirements\n  e.g. https://travis-ci.org/AndreMiras/python-for-android/builds/438840800\n  the list of recipes was huge and result was:\n  [ERROR]:   Didn't find any valid dependency graphs.\n  [ERROR]:   This means that some of your requirements pull in conflicting dependencies.\n- only rebuilds on sdl2 bootstrap\n- supports mainly python3crystax with fallback to python2, but no python3 support\n\"\"\"\nimport sh\nimport os\nfrom pythonforandroid.build import Context\nfrom pythonforandroid.graph import get_recipe_order_and_bootstrap\nfrom pythonforandroid.toolchain import current_directory\nfrom ci.constants import TargetPython, CORE_RECIPES, BROKEN_RECIPES\n\n\ndef modified_recipes(branch='origin/master'):\n    \"\"\"\n    Returns a set of modified recipes between the current branch and the one\n    in param.\n    \"\"\"\n    # using the contrib version on purpose rather than sh.git, since it comes\n    # with a bunch of fixes, e.g. disabled TTY, see:\n    # https://stackoverflow.com/a/20128598/185510\n    git_diff = sh.contrib.git.diff('--name-only', branch)\n    recipes = set()\n    for file_path in git_diff:\n        if 'pythonforandroid/recipes/' in file_path:\n            recipe = file_path.split('/')[2]\n            recipes.add(recipe)\n    return recipes\n\n\ndef build(target_python, requirements):\n    \"\"\"\n    Builds an APK given a target Python and a set of requirements.\n    \"\"\"\n    if not requirements:\n        return\n    testapp = 'setup_testapp_python2.py'\n    android_sdk_home = os.environ['ANDROID_SDK_HOME']\n    android_ndk_home = os.environ['ANDROID_NDK_HOME']\n    crystax_ndk_home = os.environ['CRYSTAX_NDK_HOME']\n    if target_python == TargetPython.python3crystax:\n        android_ndk_home = crystax_ndk_home\n        testapp = 'setup_testapp_python3.py'\n    requirements.add(target_python.name)\n    requirements = ','.join(requirements)\n    print('requirements:', requirements)\n    with current_directory('testapps/'):\n        try:\n            for line in sh.python(\n                    testapp, 'apk', '--sdk-dir', android_sdk_home,\n                    '--ndk-dir', android_ndk_home, '--bootstrap', 'sdl2', '--requirements',\n                    requirements, _err_to_out=True, _iter=True):\n                print(line)\n        except sh.ErrorReturnCode as e:\n            raise\n\n\ndef main():\n    target_python = TargetPython.python3crystax\n    recipes = modified_recipes()\n    print('recipes modified:', recipes)\n    recipes -= CORE_RECIPES\n    print('recipes to build:', recipes)\n    context = Context()\n    build_order, python_modules, bs = get_recipe_order_and_bootstrap(\n        context, recipes, None)\n    # fallback to python2 if default target is not compatible\n    if target_python.name not in build_order:\n        print('incompatible with {}'.format(target_python.name))\n        target_python = TargetPython.python2\n        print('falling back to {}'.format(target_python.name))\n    # removing the known broken recipe for the given target\n    broken_recipes = BROKEN_RECIPES[target_python]\n    recipes -= broken_recipes\n    print('recipes to build (no broken):', recipes)\n    build(target_python, recipes)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "ci/rebuild_updated_recipes.py"}, {"content": "\nfrom pythonforandroid.recipe import PythonRecipe\n\n\nclass JediRecipe(PythonRecipe):\n    # version = 'master'\n    version = 'v0.9.0'\n    url = 'https://github.com/davidhalter/jedi/archive/{version}.tar.gz'\n\n    depends = [('python2', 'python3crystax')]\n\n    patches = ['fix_MergedNamesDict_get.patch']\n    # This apparently should be fixed in jedi 0.10 (not released to\n    # pypi yet), but it still occurs on Android, I could not reproduce\n    # on desktop.\n\n    call_hostpython_via_targetpython = False\n\n\nrecipe = JediRecipe()\n", "path": "pythonforandroid/recipes/jedi/__init__.py"}], "after_files": [{"content": "from enum import Enum\n\n\nclass TargetPython(Enum):\n    python2 = 0\n    python3crystax = 1\n    python3 = 2\n\n\n# recipes that currently break the build\n# a recipe could be broken for a target Python and not for the other,\n# hence we're maintaining one list per Python target\nBROKEN_RECIPES_PYTHON2 = set([\n    # pythonhelpers.h:12:18: fatal error: string: No such file or directory\n    'atom',\n    # https://github.com/kivy/python-for-android/issues/550\n    'audiostream',\n    'brokenrecipe',\n    # https://github.com/kivy/python-for-android/issues/1409\n    'enaml',\n    'evdev',\n    # distutils.errors.DistutilsError\n    # Could not find suitable distribution for Requirement.parse('cython')\n    'ffpyplayer',\n    'flask',\n    'groestlcoin_hash',\n    'hostpython3crystax',\n    # https://github.com/kivy/python-for-android/issues/1398\n    'ifaddrs',\n    # https://github.com/kivy/python-for-android/issues/1354\n    'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',\n    'kiwisolver',\n    # https://github.com/kivy/python-for-android/issues/1399\n    'libglob',\n    'libmysqlclient',\n    'libsecp256k1',\n    'libtribler',\n    'ndghttpsclient',\n    'm2crypto',\n    'netifaces',\n    'Pillow',\n    # depends on cffi that still seems to have compilation issues\n    'protobuf_cpp',\n    'xeddsa',\n    'x3dh',\n    'pynacl',\n    'doubleratchet',\n    'omemo',\n    'cryptography',\n    # https://github.com/kivy/python-for-android/issues/1405\n    'psycopg2',\n    'pygame',\n    # most likely some setup in the Docker container, because it works in host\n    'pyjnius', 'pyopenal',\n    'pyproj',\n    'pysdl2',\n    'pyzmq',\n    'secp256k1',\n    'shapely',\n    'twisted',\n    'vlc',\n    'websocket-client',\n    'zeroconf',\n    'zope',\n])\nBROKEN_RECIPES_PYTHON3_CRYSTAX = set([\n    'brokenrecipe',\n    # enum34 is not compatible with Python 3.6 standard library\n    # https://stackoverflow.com/a/45716067/185510\n    'enum34',\n    # https://github.com/kivy/python-for-android/issues/1398\n    'ifaddrs',\n    # https://github.com/kivy/python-for-android/issues/1399\n    'libglob',\n    # cannot find -lcrystax\n    'cffi', 'pycryptodome', 'pymuk', 'secp256k1',\n    # https://github.com/kivy/python-for-android/issues/1404\n    'cryptography',\n    # https://github.com/kivy/python-for-android/issues/1294\n    'ffmpeg', 'ffpyplayer',\n    # https://github.com/kivy/python-for-android/pull/1307 ?\n    'gevent',\n    'icu',\n    # https://github.com/kivy/python-for-android/issues/1354\n    'kivent_core', 'kivent_cymunk', 'kivent_particles', 'kivent_polygen',\n    # https://github.com/kivy/python-for-android/issues/1405\n    'libpq', 'psycopg2',\n    'netifaces',\n    # https://github.com/kivy/python-for-android/issues/1315 ?\n    'opencv',\n    'protobuf_cpp',\n    # most likely some setup in the Docker container, because it works in host\n    'pyjnius', 'pyopenal',\n    # SyntaxError: invalid syntax (Python2)\n    'storm',\n    'vlc',\n])\n# to be created via https://github.com/kivy/python-for-android/issues/1514\nBROKEN_RECIPES_PYTHON3 = set([\n])\n\nBROKEN_RECIPES = {\n    TargetPython.python2: BROKEN_RECIPES_PYTHON2,\n    TargetPython.python3crystax: BROKEN_RECIPES_PYTHON3_CRYSTAX,\n    TargetPython.python3: BROKEN_RECIPES_PYTHON3,\n}\n# recipes that were already built will be skipped\nCORE_RECIPES = set([\n    'pyjnius', 'kivy', 'openssl', 'requests', 'sqlite3', 'setuptools',\n    'numpy', 'android', 'python2', 'python3',\n])\n", "path": "ci/constants.py"}, {"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nContinuous Integration helper script.\nAutomatically detects recipes modified in a changeset (compares with master)\nand recompiles them.\n\nTo run locally, set the environment variables before running:\n```\nANDROID_SDK_HOME=~/.buildozer/android/platform/android-sdk-20\nANDROID_NDK_HOME=~/.buildozer/android/platform/android-ndk-r9c\n./ci/rebuild_update_recipes.py\n```\n\nCurrent limitations:\n- will fail on conflicting requirements\n  e.g. https://travis-ci.org/AndreMiras/python-for-android/builds/438840800\n  the list of recipes was huge and result was:\n  [ERROR]:   Didn't find any valid dependency graphs.\n  [ERROR]:   This means that some of your requirements pull in conflicting dependencies.\n- only rebuilds on sdl2 bootstrap\n- supports mainly python3 with fallback to python2\n\"\"\"\nimport sh\nimport os\nfrom pythonforandroid.build import Context\nfrom pythonforandroid.graph import get_recipe_order_and_bootstrap\nfrom pythonforandroid.toolchain import current_directory\nfrom ci.constants import TargetPython, CORE_RECIPES, BROKEN_RECIPES\n\n\ndef modified_recipes(branch='origin/master'):\n    \"\"\"\n    Returns a set of modified recipes between the current branch and the one\n    in param.\n    \"\"\"\n    # using the contrib version on purpose rather than sh.git, since it comes\n    # with a bunch of fixes, e.g. disabled TTY, see:\n    # https://stackoverflow.com/a/20128598/185510\n    git_diff = sh.contrib.git.diff('--name-only', branch)\n    recipes = set()\n    for file_path in git_diff:\n        if 'pythonforandroid/recipes/' in file_path:\n            recipe = file_path.split('/')[2]\n            recipes.add(recipe)\n    return recipes\n\n\ndef build(target_python, requirements):\n    \"\"\"\n    Builds an APK given a target Python and a set of requirements.\n    \"\"\"\n    if not requirements:\n        return\n    testapp = 'setup_testapp_python2.py'\n    android_sdk_home = os.environ['ANDROID_SDK_HOME']\n    android_ndk_home = os.environ['ANDROID_NDK_HOME']\n    if target_python == TargetPython.python3:\n        testapp = 'setup_testapp_python3.py'\n    requirements.add(target_python.name)\n    requirements = ','.join(requirements)\n    print('requirements:', requirements)\n    with current_directory('testapps/'):\n        try:\n            for line in sh.python(\n                    testapp, 'apk', '--sdk-dir', android_sdk_home,\n                    '--ndk-dir', android_ndk_home, '--bootstrap', 'sdl2', '--requirements',\n                    requirements, _err_to_out=True, _iter=True):\n                print(line)\n        except sh.ErrorReturnCode as e:\n            raise\n\n\ndef main():\n    target_python = TargetPython.python3\n    recipes = modified_recipes()\n    print('recipes modified:', recipes)\n    recipes -= CORE_RECIPES\n    print('recipes to build:', recipes)\n    context = Context()\n    build_order, python_modules, bs = get_recipe_order_and_bootstrap(\n        context, recipes, None)\n    # fallback to python2 if default target is not compatible\n    if target_python.name not in build_order:\n        print('incompatible with {}'.format(target_python.name))\n        target_python = TargetPython.python2\n        print('falling back to {}'.format(target_python.name))\n    # removing the known broken recipe for the given target\n    broken_recipes = BROKEN_RECIPES[target_python]\n    recipes -= broken_recipes\n    print('recipes to build (no broken):', recipes)\n    build(target_python, recipes)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "ci/rebuild_updated_recipes.py"}, {"content": "from pythonforandroid.recipe import PythonRecipe\n\n\nclass JediRecipe(PythonRecipe):\n    version = 'v0.9.0'\n    url = 'https://github.com/davidhalter/jedi/archive/{version}.tar.gz'\n\n    depends = [('python2', 'python3crystax', 'python3')]\n\n    patches = ['fix_MergedNamesDict_get.patch']\n    # This apparently should be fixed in jedi 0.10 (not released to\n    # pypi yet), but it still occurs on Android, I could not reproduce\n    # on desktop.\n\n    call_hostpython_via_targetpython = False\n\n\nrecipe = JediRecipe()\n", "path": "pythonforandroid/recipes/jedi/__init__.py"}]}