Commit aaac7b08 authored by Romain Casati's avatar Romain Casati
Browse files

Taking into account order when hacking dependencies.

parent e818a2a5
......@@ -7,6 +7,7 @@ It manage Pyodide and Basthon's modules load.
import pyodide
import js
from . import _hack_modules
from .utils import OrderedSet
__author__ = "Romain Casati"
......@@ -111,13 +112,17 @@ def _load_internal(packages):
def _internal_dependencies(packages):
""" Return the set of dependencies of a list of internal packages. """
"""
Return the (ordered) set of dependencies of a list of internal packages.
Order maters: last elements should be loaded first.
"""
def dependencies(package):
deps = set(_internal_pkgs_dict.get(package, {}).get("deps", []))
deps = OrderedSet(_internal_pkgs_dict.get(package, {}).get("deps", []))
return deps.union(*(dependencies(p) for p in deps))
packages = set(packages)
return set.union(*(dependencies(p) for p in packages)) - packages
packages = OrderedSet(packages)
return OrderedSet.union(*(dependencies(p) for p in packages)) - packages
def load_and_hack(packages):
......@@ -126,12 +131,14 @@ def load_and_hack(packages):
packages = [packages]
# remove already loaded
packages = set(packages) - _loaded
packages = OrderedSet(packages) - _loaded
if not packages:
return js.Promise.resolve()
packages = packages | _internal_dependencies(packages)
# last dependencies first to ensure deps are resolved when hacking
# the order is guarenteed by our OrderedSet
packages = reversed(packages | _internal_dependencies(packages))
pyodide_packages = packages & _pyodide_pkgs
internal_packages = packages & _internal_pkgs
......
"""
Some usefull stuff.
"""
__author__ = "Romain Casati"
__license__ = "GNU GPL v3"
__email__ = "romain.casati@basthon.fr"
__all__ = ["OrderedSet"]
class OrderedSet(dict):
"""
A set preserving insertion order based on a dict
(since as of Python 3.7, dicts preserve order).
Implementation is not intended to be efficient since it
will be used with very few elements in Basthon.
"""
def __init__(self, *args, **kwargs):
if kwargs:
raise ValueError("Named arguments not allowed.")
super().__init__()
self.update(*args)
def add(self, elem):
self[elem] = None
def remove(self, elem):
del self[elem]
def discard(self, elem):
dict.pop(self, elem, None)
def pop(self):
return self.popitem()[0]
def copy(self):
return OrderedSet(self)
def update(self, *others):
for a in others:
for k in a:
self.add(k)
def union(self, *others):
return OrderedSet(self, *others)
def difference_update(self, *others):
for o in others:
for k in o:
self.discard(k)
def difference(self, *others):
res = self.copy()
res.difference_update(*others)
return res
def symmetric_difference_update(self, other):
for k in other:
if k in self:
self.discard(k)
else:
self.add(k)
def symmetric_difference(self, other):
res = self.copy()
res.symmetric_difference_update(other)
return res
def intersection_update(self, *others):
self.difference_update(*([k for k in self if k not in o]
for o in others))
def intersection(self, *others):
res = self.copy()
res.intersection_update(*others)
return res
def __and__(self, other):
return self.intersection(other)
def __xor__(self, other):
return self.symmetric_difference(other)
def __or__(self, other):
return self.union(other)
def __sub__(self, other):
return self.difference(other)
def __reversed__(self):
return OrderedSet(dict.__reversed__(self))
def __repr__(self):
return f"{{{', '.join(str(k) for k in self)}}}"
def __str__(self):
return repr(self)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment