Skip to content

Commit

Permalink
fix: correctly report lineno (#2584)
Browse files Browse the repository at this point in the history
### Description

fix: #2583, #1256 and #2574

### QC
maybe #2583

* [ ] The PR contains a test case for the changes or the changes are
already covered by an existing test case.
* [ ] The documentation (`docs/`) is updated to reflect the changes or
this is not necessary (e.g. if the change does neither modify the
language nor the behavior or functionalities of Snakemake).

---------

Co-authored-by: Johannes Köster <johannes.koester@tu-dortmund.de>
  • Loading branch information
Hocnonsense and johanneskoester committed Jan 8, 2024
1 parent d47b1d2 commit 967a0d7
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
14 changes: 10 additions & 4 deletions snakemake/exceptions.py
Expand Up @@ -160,6 +160,12 @@ def print_exception(ex, linemaps=None):
traceback.print_exception(type(ex), ex, ex.__traceback__)


def update_lineno(ex: SyntaxError, linemaps):
if ex.filename and ex.lineno:
ex.lineno = linemaps[ex.filename][ex.lineno]
return ex


class SourceFileError(WorkflowError):
def __init__(self, msg):
super().__init__(f"Error in source file definition: {msg}")
Expand Down Expand Up @@ -188,18 +194,18 @@ def __init__(
snakefile -- the file the exception originates
"""
super(RuleException, self).__init__(message)
self._include = set()
_include = set()
if include:
for ex in include:
self._include.add(ex)
self._include.update(ex._include)
_include.add(ex)
_include.update(ex._include)
if rule is not None:
if lineno is None:
lineno = rule.lineno
if snakefile is None:
snakefile = rule.snakefile

self._include = list(self._include)
self._include = list(_include)
self.rule = rule
self.lineno = lineno
self.filename = snakefile
Expand Down
15 changes: 12 additions & 3 deletions snakemake/workflow.py
Expand Up @@ -57,6 +57,7 @@
UnknownRuleException,
NoRulesException,
WorkflowError,
update_lineno,
)
from snakemake.dag import DAG, ChangeType
from snakemake.scheduler import JobScheduler
Expand Down Expand Up @@ -164,7 +165,7 @@ def __post_init__(self):
self._linemaps = dict()
self.rule_count = 0
self.included = []
self.included_stack = []
self.included_stack: list[SourceFile] = []
self._persistence: Optional[Persistence] = None
self._dag: Optional[DAG] = None
self._onsuccess = lambda log: None
Expand Down Expand Up @@ -1353,14 +1354,22 @@ def include(
if print_compilation:
print(code)

if isinstance(snakefile, LocalSourceFile):
snakefile_path_or_uri = snakefile.get_basedir().get_path_or_uri()
if (
isinstance(snakefile, LocalSourceFile)
and snakefile_path_or_uri not in sys.path
):
# insert the current directory into sys.path
# this allows to import modules from the workflow directory
sys.path.insert(0, snakefile.get_basedir().get_path_or_uri())

self.linemaps[snakefile.get_path_or_uri()] = linemap

exec(compile(code, snakefile.get_path_or_uri(), "exec"), self.globals)
try:
exec(compile(code, snakefile.get_path_or_uri(), "exec"), self.globals)
except SyntaxError as e:
e = update_lineno(e, self.linemaps)
raise

if not overwrite_default_target:
self.default_target = default_target
Expand Down

0 comments on commit 967a0d7

Please sign in to comment.