Skip to content

Commit 0089e58

Browse files
authored
Merge pull request #22 from pyiron/warn
Log a warning when an executable is found, but does not have the exec…
2 parents 4d26756 + efd976c commit 0089e58

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

pyiron_snippets/resources.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from glob import glob
1313
import re
1414
from typing import Any
15+
import warnings
1516

1617
if os.name == "nt":
1718
EXE_SUFFIX = "bat"
@@ -23,6 +24,10 @@ class ResourceNotFound(RuntimeError):
2324
pass
2425

2526

27+
class ResolverWarning(RuntimeWarning):
28+
pass
29+
30+
2631
class AbstractResolver(ABC):
2732
"""
2833
Interface for resolvers.
@@ -204,6 +209,9 @@ class ExecutableResolver(AbstractResolver):
204209
and have the executable bit set. :meth:`.search` yields tuples of version strings and full paths to the executable
205210
instead of plain strings.
206211
212+
Except on windows results are filtered to make sure all returned scripts have the executable bit set.
213+
When the bit is not set, a warning is printed.
214+
207215
>>> exe = ExecutableResolver(..., "lammps")
208216
>>> exe.list() # doctest: +SKIP
209217
[
@@ -255,9 +263,18 @@ def _search(self, name):
255263

256264
def cond(path):
257265
isfile = os.path.isfile(path)
266+
# HINT: this is always True on windows
258267
isexec = os.access(
259268
path, os.X_OK, effective_ids=os.access in os.supports_effective_ids
260269
)
270+
if isfile and not isexec:
271+
warnings.warn(
272+
f"Found file '{path}', but skipping it because it is not executable!",
273+
category=ResolverWarning,
274+
# TODO: maybe used from python3.12 onwards
275+
# skip_file_prefixes=(os.path.dirname(__file__),),
276+
stacklevel=4,
277+
)
261278
return isfile and isexec
262279

263280
for path in filter(cond, self._resolver.search(self._glob)):

tests/unit/test_resources.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import os.path
33
import unittest
4-
from pyiron_snippets.resources import ResourceNotFound, ResourceResolver, ExecutableResolver
4+
from pyiron_snippets.resources import ResourceNotFound, ResourceResolver, ExecutableResolver, ResolverWarning
55

66
class TestResolvers(unittest.TestCase):
77
"""
@@ -55,8 +55,10 @@ def test_executable(self):
5555
for suffix in (None, "sh", "bat"):
5656
with self.subTest(suffix=suffix):
5757
res = ExecutableResolver([self.res1], code="code1", module="module1", suffix=suffix)
58+
# Windows always reports the exec bit as set, so skip those tests there
5859
if os.name != "nt":
59-
# no exec bits are present on windows it seems
60+
with self.assertWarns(ResolverWarning):
61+
res.list()
6062
self.assertNotIn("versionnonexec", res.available_versions,
6163
"ExecutableResolver must not list scripts that are not executable.")
6264
self.assertNotIn("wrong_format", res.available_versions,

0 commit comments

Comments
 (0)