Skip to content

Commit 3fcb454

Browse files
committed
add context manager
1 parent 657d727 commit 3fcb454

File tree

2 files changed

+46
-40
lines changed

2 files changed

+46
-40
lines changed

pycyphal/dsdl/_compiler.py

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -185,50 +185,48 @@ def compile( # pylint: disable=redefined-builtin
185185
language_context=language_context,
186186
)
187187

188-
lockfile = Locker(
188+
with Locker(
189189
root_namespace_name=root_namespace_name if root_namespace_name else "_support_",
190190
output_directory=output_directory,
191-
)
192-
if lockfile.create():
193-
# Generate code
194-
assert isinstance(output_directory, pathlib.Path)
195-
code_generator = nunavut.jinja.DSDLCodeGenerator(
196-
namespace=root_ns,
197-
generate_namespace_types=nunavut.YesNoDefault.YES,
198-
followlinks=True,
199-
)
200-
code_generator.generate_all()
201-
_logger.info(
202-
"Generated %d types from the root namespace %r in %.1f seconds",
203-
len(composite_types),
204-
root_namespace_name,
205-
time.monotonic() - started_at,
206-
)
207-
208-
support_generator = nunavut.jinja.SupportGenerator(
209-
namespace=root_ns,
210-
)
211-
support_generator.generate_all()
212-
213-
# A minor UX improvement; see https://github.com/OpenCyphal/pycyphal/issues/115
214-
for p in sys.path:
215-
if pathlib.Path(p).resolve() == pathlib.Path(output_directory):
216-
break
217-
else:
218-
if os.name == "nt":
219-
quick_fix = f'Quick fix: `$env:PYTHONPATH += ";{output_directory.resolve()}"`'
220-
elif os.name == "posix":
221-
quick_fix = f'Quick fix: `export PYTHONPATH="{output_directory.resolve()}"`'
222-
else:
223-
quick_fix = "Quick fix is not available for this OS."
191+
) as lockfile:
192+
if lockfile:
193+
# Generate code
194+
assert isinstance(output_directory, pathlib.Path)
195+
code_generator = nunavut.jinja.DSDLCodeGenerator(
196+
namespace=root_ns,
197+
generate_namespace_types=nunavut.YesNoDefault.YES,
198+
followlinks=True,
199+
)
200+
code_generator.generate_all()
224201
_logger.info(
225-
"Generated package is stored in %r, which is not in Python module search path list. "
226-
"The package will fail to import unless you add the destination directory to sys.path or PYTHONPATH. %s",
227-
str(output_directory),
228-
quick_fix,
202+
"Generated %d types from the root namespace %r in %.1f seconds",
203+
len(composite_types),
204+
root_namespace_name,
205+
time.monotonic() - started_at,
229206
)
230207

231-
lockfile.remove()
208+
support_generator = nunavut.jinja.SupportGenerator(
209+
namespace=root_ns,
210+
)
211+
support_generator.generate_all()
212+
213+
# A minor UX improvement; see https://github.com/OpenCyphal/pycyphal/issues/115
214+
for p in sys.path:
215+
if pathlib.Path(p).resolve() == pathlib.Path(output_directory):
216+
break
217+
else:
218+
if os.name == "nt":
219+
quick_fix = f'Quick fix: `$env:PYTHONPATH += ";{output_directory.resolve()}"`'
220+
elif os.name == "posix":
221+
quick_fix = f'Quick fix: `export PYTHONPATH="{output_directory.resolve()}"`'
222+
else:
223+
quick_fix = "Quick fix is not available for this OS."
224+
_logger.info(
225+
"Generated package is stored in %r, which is not in Python module search path list. "
226+
"The package will fail to import unless you add the destination directory to sys.path or PYTHONPATH. %s",
227+
str(output_directory),
228+
quick_fix,
229+
)
232230

233231
return GeneratedPackageInfo(
234232
path=pathlib.Path(output_directory) / pathlib.Path(root_namespace_name),

pycyphal/dsdl/_lockfile.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44
from io import TextIOWrapper
55
from pathlib import Path
6+
from types import TracebackType
67

78
_logger = logging.getLogger(__name__)
89

@@ -18,12 +19,19 @@ def __init__(self, output_directory: pathlib.Path, root_namespace_name: str) ->
1819
def _lockfile_path(self) -> Path:
1920
return self._output_directory / f"{self._root_namespace_name}.lock"
2021

22+
def __enter__(self) -> bool:
23+
return self.create()
24+
25+
def __exit__(
26+
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
27+
) -> None:
28+
return self.remove()
29+
2130
def create(self) -> bool:
2231
"""
2332
True means compilation needs to proceed.
2433
False means another process already compiled the namespace so we just waited for the lockfile to disappear before returning.
2534
"""
26-
# TODO Read about context manager
2735
try:
2836
pathlib.Path(self._output_directory).mkdir(parents=True, exist_ok=True)
2937
self._lockfile = open(self._lockfile_path, "x")

0 commit comments

Comments
 (0)