-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
AttributeError: 'Context' object has no attribute 'hostpython' #1077
Comments
I'm not sure buildozer is actually using python-for-android master here. Would you be able to paste the contents of the file |
I'm fairly sure that buildozer is using the stable branch, which does not yet include the recipe graph fixes, so I'll close this issue. Feel free to reopen it if you believe buildozer is using the master branch (but it probably won't be unless you've manually changed that). |
Here you go.
BTW, I added python2 as a requirement in my buildozer.spec file and it then
worked fine.
Cheers,
Rick
from copy import deepcopy
from pythonforandroid.logger import (info, info_notify, warning)
from pythonforandroid.recipe import Recipe
from pythonforandroid.bootstrap import Bootstrap
class Graph(object):
# Taken from the old python-for-android/depsort
# Modified to include alternative dependencies
def __init__(self):
# `graph`: dict that maps each package to a set of its dependencies.
self.graphs = [{}]
# self.graph = {}
def remove_redundant_graphs(self):
'''Removes possible graphs if they are equivalent to others.'''
graphs = self.graphs
# Walk the list backwards so that popping elements doesn't
# mess up indexing.
# n.b. no need to test graph 0 as it will have been tested against
# all others by the time we get to it
for i in range(len(graphs) - 1, 0, -1):
graph = graphs[i]
# test graph i against all graphs 0 to i-1
for j in range(0, i):
comparison_graph = graphs[j]
if set(comparison_graph.keys()) == set(graph.keys()):
# graph[i] == graph[j]
# so remove graph[i] and continue on to testing
graph[i-1]
graphs.pop(i)
break
def add(self, dependent, dependency):
"""Add a dependency relationship to the graph"""
if isinstance(dependency, (tuple, list)):
for graph in self.graphs[:]:
for dep in dependency[1:]:
new_graph = deepcopy(graph)
self._add(new_graph, dependent, dep)
self.graphs.append(new_graph)
self._add(graph, dependent, dependency[0])
else:
for graph in self.graphs:
self._add(graph, dependent, dependency)
self.remove_redundant_graphs()
def _add(self, graph, dependent, dependency):
'''Add a dependency relationship to a specific graph, where
dependency
must be a single dependency, not a list or tuple.
'''
graph.setdefault(dependent, set())
graph.setdefault(dependency, set())
if dependent != dependency:
graph[dependent].add(dependency)
def conflicts(self, conflict):
graphs = self.graphs
initial_num = len(graphs)
for i in range(len(graphs)):
graph = graphs[initial_num - 1 - i]
if conflict in graph:
graphs.pop(initial_num - 1 - i)
return len(graphs) == 0
def remove_remaining_conflicts(self, ctx):
# It's unpleasant to have to pass ctx as an argument...
'''Checks all possible graphs for conflicts that have arisen during
the additon of alternative repice branches, as these are not checked
for conflicts at the time.'''
new_graphs = []
for i, graph in enumerate(self.graphs):
for name in graph.keys():
recipe = Recipe.get_recipe(name, ctx)
if any([c in graph for c in recipe.conflicts]):
break
else:
new_graphs.append(graph)
self.graphs = new_graphs
def add_optional(self, dependent, dependency):
"""Add an optional (ordering only) dependency relationship to the
graph
Only call this after all mandatory requirements are added
"""
for graph in self.graphs:
if dependent in graph and dependency in graph:
self._add(graph, dependent, dependency)
def find_order(self, index=0):
"""Do a topological sort on a dependency graph
:Parameters:
:Returns:
iterator, sorted items form first to last
"""
graph = self.graphs[index]
graph = dict((k, set(v)) for k, v in graph.items())
while graph:
# Find all items without a parent
leftmost = [l for l, s in graph.items() if not s]
if not leftmost:
raise ValueError('Dependency cycle detected! %s' % graph)
# If there is more than one, sort them for predictable order
leftmost.sort()
for result in leftmost:
# Yield and remove them from the graph
yield result
graph.pop(result)
for bset in graph.values():
bset.discard(result)
def get_recipe_order_and_bootstrap(ctx, names, bs=None):
'''Takes a list of recipe names and (optionally) a bootstrap. Then
works out the dependency graph (including bootstrap recipes if
necessary). Finally, if no bootstrap was initially selected,
chooses one that supports all the recipes.
'''
graph = Graph()
recipes_to_load = set(names)
if bs is not None and bs.recipe_depends:
info_notify('Bootstrap requires recipes
{}'.format(bs.recipe_depends))
recipes_to_load = recipes_to_load.union(set(bs.recipe_depends))
recipes_to_load = list(recipes_to_load)
recipe_loaded = []
python_modules = []
while recipes_to_load:
name = recipes_to_load.pop(0)
if name in recipe_loaded or isinstance(name, (list, tuple)):
continue
try:
recipe = Recipe.get_recipe(name, ctx)
except IOError:
info('No recipe named {}; will attempt to install with pip'
.format(name))
python_modules.append(name)
continue
except (KeyboardInterrupt, SystemExit):
raise
except:
warning('Failed to import recipe named {}; the recipe exists '
'but appears broken.'.format(name))
warning('Exception was:')
raise
graph.add(name, name)
info('Loaded recipe {} (depends on {}{})'.format(
name, recipe.depends,
', conflicts {}'.format(recipe.conflicts) if recipe.conflicts
else ''))
for depend in recipe.depends:
graph.add(name, depend)
recipes_to_load += recipe.depends
for conflict in recipe.conflicts:
if graph.conflicts(conflict):
warning(
('{} conflicts with {}, but both have been '
'included or pulled into the requirements.'
.format(recipe.name, conflict)))
warning(
'Due to this conflict the build cannot continue,
exiting.')
exit(1)
python_modules += recipe.python_depends
recipe_loaded.append(name)
graph.remove_remaining_conflicts(ctx)
if len(graph.graphs) > 1:
info('Found multiple valid recipe sets:')
for g in graph.graphs:
info(' {}'.format(g.keys()))
info_notify('Using the first of these: {}'
.format(graph.graphs[0].keys()))
elif len(graph.graphs) == 0:
warning('Didn\'t find any valid dependency graphs, exiting.')
exit(1)
else:
info('Found a single valid recipe set (this is good)')
build_order = list(graph.find_order(0))
if bs is None: # It would be better to check against possible
# orders other than the first one, but in practice
# there will rarely be clashes, and the user can
# specify more parameters if necessary to resolve
# them.
bs = Bootstrap.get_bootstrap_from_recipes(build_order, ctx)
if bs is None:
info('Could not find a bootstrap compatible with the '
'required recipes.')
info('If you think such a combination should exist, try '
'specifying the bootstrap manually with --bootstrap.')
exit(1)
info('{} bootstrap appears compatible with the required recipes.'
.format(bs.name))
info('Checking this...')
recipes_to_load = bs.recipe_depends
# This code repeats the code from earlier! Should move to a
function:
while recipes_to_load:
name = recipes_to_load.pop(0)
if name in recipe_loaded or isinstance(name, (list, tuple)):
continue
try:
recipe = Recipe.get_recipe(name, ctx)
except ImportError:
info('No recipe named {}; will attempt to install with pip'
.format(name))
python_modules.append(name)
continue
graph.add(name, name)
info('Loaded recipe {} (depends on {}{})'.format(
name, recipe.depends,
', conflicts {}'.format(recipe.conflicts) if
recipe.conflicts
else ''))
for depend in recipe.depends:
graph.add(name, depend)
recipes_to_load += recipe.depends
for conflict in recipe.conflicts:
if graph.conflicts(conflict):
warning(
('{} conflicts with {}, but both have been '
'included or pulled into the requirements.'
.format(recipe.name, conflict)))
warning('Due to this conflict the build cannot
continue, '
'exiting.')
exit(1)
recipe_loaded.append(name)
graph.remove_remaining_conflicts(ctx)
build_order = list(graph.find_order(0))
build_order, python_modules, bs = get_recipe_order_and_bootstrap(
ctx, build_order + python_modules, bs)
return build_order, python_modules, bs
# Do a final check that the new bs doesn't pull in any conflicts
…On Sun, Jul 16, 2017 at 4:39 PM, Alexander Taylor ***@***.***> wrote:
I'm not sure buildozer is actually using python-for-android master here.
Would you be able to paste the contents of the file
/home/rick/Desktop/osenergy/buildozer_tutorial/.buildozer/
android/platform/python-for-android-master/pythonforandroid/graph.py?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1077 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AKqQs-RnkkYNi4cqvI_iof-SE-sTHbCjks5sOnT8gaJpZM4OZZs8>
.
|
Yep, this is definitely the old version of the module. Adding Thanks for the report! |
ok Alexander, makes sense. I didnt make any mods to that.
Cheers,
Rick
…On Sun, Jul 16, 2017 at 5:01 PM, Alexander Taylor ***@***.***> wrote:
I'm fairly sure that buildozer is using the stable branch, which does not
yet include the recipe graph fixes, so I'll close this issue. Feel free to
reopen it if you believe buildozer is using the master branch (but it
probably won't be unless you've manually changed that).
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1077 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AKqQs3GPZtc7IH77Id0ra4-M28TxYtEdks5sOnoOgaJpZM4OZZs8>
.
|
It did, :)
Thanks for the fast response !!
Rick
…On Sun, Jul 16, 2017 at 5:11 PM, Alexander Taylor ***@***.***> wrote:
Yep, this is definitely the old version of the module. Adding python2 in
the requirements should totally resolve the issue until the fix is in the
stable branch.
Thanks for the report!
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1077 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AKqQs6ga_HxBJ3RjqWXSZsUL8YG3aPQXks5sOnyGgaJpZM4OZZs8>
.
|
#Still seems to be a problem. May be related to #1064
First attempt to deploy a simple kivy/python3 android app.
Linux kali-Alien 4.9.0-kali4-amd64 #1 SMP Debian 4.9.30-2kali1 (2017-06-22) x86_64 GNU/Linux
level 2 debug
The text was updated successfully, but these errors were encountered: