Skip to content

Commit 47bfacc

Browse files
committed
compile: Support relative imports.
1 parent 1dbc505 commit 47bfacc

File tree

3 files changed

+14
-8
lines changed

3 files changed

+14
-8
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
### Added
10+
- Experimental support for relative and nested imports.
11+
912
## [1.0.0-alpha.30] - 2022-08-26
1013

1114
### Added

demo/multidemo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from pybricks.hubs import ThisHub
22
from pybricks.parameters import Color
33
from pybricks.tools import wait
4-
from module2 import nice_color
4+
from .module2 import nice_color
55

66
hub = ThisHub()
77
hub.light.on(Color.RED)

pybricksdev/compile.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ async def compile_multi_file(
8383
):
8484
"""Compiles a Python file and its dependencies with ``mpy-cross``.
8585
86-
All dependencies must be Python modules from the same folder.
86+
On the hub, all dependencies behave as independent modules. Any (leading)
87+
dots will be considered to be part of the module name. As such, relative
88+
or "package" imports will work, but there is no handling of __init__, etc.
8789
8890
The returned bytes format is of the form:
8991
@@ -95,8 +97,6 @@ async def compile_multi_file(
9597
- second script mpy data
9698
- ...
9799
98-
All components are 0-padded to a size with multiple of 4.
99-
100100
If the main script does not import any local module, it returns only the
101101
first script mpy data (without size and name) for backwards compatibility
102102
with older firmware.
@@ -131,7 +131,8 @@ async def compile_multi_file(
131131
# Find all dependencies recursively
132132
def find_dependencies(module_name):
133133
try:
134-
with open(source_dir / (module_name + ".py")) as source:
134+
path = source_dir / Path(*module_name.split(".")).with_suffix(".py")
135+
with open(path) as source:
135136
# Search non-recursively through current module
136137
local_dependencies = set()
137138
for line in source:
@@ -142,8 +143,8 @@ def find_dependencies(module_name):
142143
elif result := re.search("import (.*)", line):
143144
local_dependencies.add(result.group(1))
144145

145-
# If each file that wasn't already done, add it and find its
146-
# dependencies too.
146+
# Add each file that wasn't already done, and find its
147+
# dependencies.
147148
for dep in local_dependencies.difference(dependencies):
148149
if dep not in dependencies:
149150
dependencies.add(dep)
@@ -174,7 +175,9 @@ def find_dependencies(module_name):
174175
blob = bytearray([])
175176
for module in modules:
176177
name = module.encode() + b"\x00"
177-
mpy = await compile_file(source_dir / (module + ".py"), abi)
178+
mpy = await compile_file(
179+
source_dir / Path(*module.split(".")).with_suffix(".py"), abi
180+
)
178181
size = len(mpy).to_bytes(4, "little")
179182
blob += size + name + mpy
180183
return blob

0 commit comments

Comments
 (0)