Skip to content

Commit 7b21c46

Browse files
committed
Ignores Python 2 import_recipe() warnings
Python 2 raises warnings on `imp.load_source()` when the module name contains dots. Ignoring this warning makes p4a output/logs more readable. Also refactors to make the code more readable. Note that for some reason the regression test will only catch the regression if ran isolated, e.g. via: ```sh tox -e py27 -- tests/test_recipe.py::TestRecipe::test_import_recipe ```
1 parent 6b12281 commit 7b21c46

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

pythonforandroid/recipe.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from os.path import basename, dirname, exists, isdir, isfile, join, realpath, split
2-
import importlib
32
import glob
43
from shutil import rmtree
54
from six import PY2, with_metaclass
@@ -21,22 +20,27 @@
2120
from pythonforandroid.util import (urlretrieve, current_directory, ensure_dir,
2221
BuildInterruptingException)
2322

24-
# this import is necessary to keep imp.load_source from complaining :)
25-
if PY2:
26-
import imp
27-
import_recipe = imp.load_source
28-
else:
29-
import importlib.util
30-
if hasattr(importlib.util, 'module_from_spec'):
31-
def import_recipe(module, filename):
23+
24+
def import_recipe(module, filename):
25+
if PY2:
26+
import imp
27+
import warnings
28+
with warnings.catch_warnings():
29+
# ignores warnings raised by hierarchical module names
30+
# (names containing dots) on Python 2
31+
warnings.simplefilter("ignore", RuntimeWarning)
32+
return imp.load_source(module, filename)
33+
else:
34+
# Python 3.5+
35+
import importlib.util
36+
if hasattr(importlib.util, 'module_from_spec'):
3237
spec = importlib.util.spec_from_file_location(module, filename)
3338
mod = importlib.util.module_from_spec(spec)
3439
spec.loader.exec_module(mod)
3540
return mod
36-
else:
37-
from importlib.machinery import SourceFileLoader
38-
39-
def import_recipe(module, filename):
41+
else:
42+
# Python 3.3 and 3.4:
43+
from importlib.machinery import SourceFileLoader
4044
return SourceFileLoader(module, filename).load_module()
4145

4246

tests/test_recipe.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import os
12
import types
23
import unittest
4+
import warnings
35
from pythonforandroid.build import Context
4-
from pythonforandroid.recipe import Recipe
6+
from pythonforandroid.recipe import Recipe, import_recipe
57

68

79
class TestRecipe(unittest.TestCase):
@@ -41,3 +43,18 @@ def test_get_recipe(self):
4143
Recipe.get_recipe(recipe_name, ctx)
4244
self.assertEqual(
4345
e.exception.args[0], 'Recipe does not exist: {}'.format(recipe_name))
46+
47+
def test_import_recipe(self):
48+
"""
49+
Verifies we can dynamically import a recipe without warnings.
50+
"""
51+
p4a_root_dir = os.path.dirname(os.path.dirname(__file__))
52+
name = 'pythonforandroid.recipes.python3'
53+
pathname = os.path.join(
54+
*([p4a_root_dir] + name.split('.') + ['__init__.py'])
55+
)
56+
with warnings.catch_warnings(record=True) as recorded_warnings:
57+
warnings.simplefilter("always")
58+
module = import_recipe(name, pathname)
59+
assert module is not None
60+
assert recorded_warnings == []

0 commit comments

Comments
 (0)