nf-core / nf-core/tools

modules lint can't handle nested environment.yml files

Open
#3,436 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
322
Forks
255
Avg merge
2d 3h
Merged PRs (30d)
5

Description

Description of the bug

As shown in https://github.com/nf-core/modules/pull/7399 nf-core tools breaks for correctly formated environment yaml files, that contain pip dependencies, e.g. https://github.com/nf-core/modules/blob/efd030110f637f845fbefc1120c2724bd852aa41/modules/nf-core/doubletdetection/environment.yml

Command used and terminal output
nf-core modules lint doubletdetection


                                          ,--./,-.
          ___     __   __   __   ___     /,-._.--~\
    |\ | |__  __ /  ` /  \ |__) |__         }  {
    | \| |       \__, \__/ |  \ |___     \`-._,-`-,
                                          `._,._,'

    nf-core/tools version 3.3.0.dev0 - https://nf-co.re


INFO     Linting modules repo: '.'
INFO     Linting module: 'doubletdetection'
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/bin/nf-core:8 in <module>          │
│                                                                                                  │
│   5 from nf_core.__main__ import run_nf_core                                                     │
│   6 if __name__ == '__main__':                                                                   │
│   7 │   sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])                         │
│ ❱ 8 │   sys.exit(run_nf_core())                                                                  │
│   9                                                                                              │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/__main__.py:182 in run_nf_core                                │
│                                                                                                  │
│    179 │   │   │   log.debug(f"Could not check latest version: {e}")                             │
│    180 │   │   stderr.print("\n")                                                                │
│    181 │   # Launch the click cli                                                                │
│ ❱  182 │   nf_core_cli(auto_envvar_prefix="NFCORE")                                              │
│    183                                                                                           │
│    184                                                                                           │
│    185 @tui(                                                                                     │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/rich_c │
│ lick/rich_command.py:367 in __call__                                                             │
│                                                                                                  │
│   364 │   │   # Include this here because I run into a false warning                             │
│   365 │   │   # in the PyCharm IDE otherwise; for some reason PyCharm doesn't                    │
│   366 │   │   # seem to think RichGroups are callable. (No issues with Mypy, though.)            │
│ ❱ 367 │   │   return super().__call__(*args, **kwargs)                                           │
│   368                                                                                            │
│   369                                                                                            │
│   370 class RichCommandCollection(CommandCollection, RichGroup):                                 │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ core.py:1157 in __call__                                                                         │
│                                                                                                  │
│   1154 │                                                                                         │
│   1155 │   def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any:                           │
│   1156 │   │   """Alias for :meth:`main`."""                                                     │
│ ❱ 1157 │   │   return self.main(*args, **kwargs)                                                 │
│   1158                                                                                           │
│   1159                                                                                           │
│   1160 class Command(BaseCommand):                                                               │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/rich_c │
│ lick/rich_command.py:152 in main                                                                 │
│                                                                                                  │
│   149 │   │   try:                                                                               │
│   150 │   │   │   try:                                                                           │
│   151 │   │   │   │   with self.make_context(prog_name, args, **extra) as ctx:                   │
│ ❱ 152 │   │   │   │   │   rv = self.invoke(ctx)                                                  │
│   153 │   │   │   │   │   if not standalone_mode:                                                │
│   154 │   │   │   │   │   │   return rv                                                          │
│   155 │   │   │   │   │   # it's not safe to `ctx.exit(rv)` here!                                │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ core.py:1688 in invoke                                                                           │
│                                                                                                  │
│   1685 │   │   │   │   super().invoke(ctx)                                                       │
│   1686 │   │   │   │   sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)                    │
│   1687 │   │   │   │   with sub_ctx:                                                             │
│ ❱ 1688 │   │   │   │   │   return _process_result(sub_ctx.command.invoke(sub_ctx))               │
│   1689 │   │                                                                                     │
│   1690 │   │   # In chain mode we create the contexts step by step, but after the                │
│   1691 │   │   # base command has been invoked.  Because at that point we do not                 │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ core.py:1688 in invoke                                                                           │
│                                                                                                  │
│   1685 │   │   │   │   super().invoke(ctx)                                                       │
│   1686 │   │   │   │   sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)                    │
│   1687 │   │   │   │   with sub_ctx:                                                             │
│ ❱ 1688 │   │   │   │   │   return _process_result(sub_ctx.command.invoke(sub_ctx))               │
│   1689 │   │                                                                                     │
│   1690 │   │   # In chain mode we create the contexts step by step, but after the                │
│   1691 │   │   # base command has been invoked.  Because at that point we do not                 │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ core.py:1434 in invoke                                                                           │
│                                                                                                  │
│   1431 │   │   │   echo(style(message, fg="red"), err=True)                                      │
│   1432 │   │                                                                                     │
│   1433 │   │   if self.callback is not None:                                                     │
│ ❱ 1434 │   │   │   return ctx.invoke(self.callback, **ctx.params)                                │
│   1435 │                                                                                         │
│   1436 │   def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:  │
│   1437 │   │   """Return a list of completions for the incomplete value. Looks                   │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ core.py:783 in invoke                                                                            │
│                                                                                                  │
│    780 │   │                                                                                     │
│    781 │   │   with augment_usage_errors(__self):                                                │
│    782 │   │   │   with ctx:                                                                     │
│ ❱  783 │   │   │   │   return __callback(*args, **kwargs)                                        │
│    784 │                                                                                         │
│    785 │   def forward(                                                                          │
│    786 │   │   __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any  # noqa: B902             │
│                                                                                                  │
│ /opt/homebrew/Caskroom/miniconda/base/envs/nfcore-tools-py3_8/lib/python3.8/site-packages/click/ │
│ decorators.py:33 in new_func                                                                     │
│                                                                                                  │
│    30 │   """                                                                                    │
│    31 │                                                                                          │
│    32 │   def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R":                            │
│ ❱  33 │   │   return f(get_current_context(), *args, **kwargs)                                   │
│    34 │                                                                                          │
│    35 │   return update_wrapper(new_func, f)                                                     │
│    36                                                                                            │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/__main__.py:1299 in command_modules_lint                      │
│                                                                                                  │
│   1296 │   """                                                                                   │
│   1297 │   Lint one or more modules in a directory.                                              │
│   1298 │   """                                                                                   │
│ ❱ 1299 │   modules_lint(ctx, tool, directory, registry, key, all, fail_warned, local, passed, s  │
│   1300                                                                                           │
│   1301                                                                                           │
│   1302 # nf-core modules info                                                                    │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/commands_modules.py:288 in modules_lint                       │
│                                                                                                  │
│   285 │   │   │   no_pull=ctx.obj["modules_repo_no_pull"],                                       │
│   286 │   │   │   hide_progress=ctx.obj["hide_progress"],                                        │
│   287 │   │   )                                                                                  │
│ ❱ 288 │   │   module_lint.lint(                                                                  │
│   289 │   │   │   module=tool,                                                                   │
│   290 │   │   │   registry=registry,                                                             │
│   291 │   │   │   key=key,                                                                       │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/modules/lint/__init__.py:174 in lint                          │
│                                                                                                  │
│   171 │   │                                                                                      │
│   172 │   │   # Lint nf-core modules                                                             │
│   173 │   │   if not local and len(remote_modules) > 0:                                          │
│ ❱ 174 │   │   │   self.lint_modules(remote_modules, registry=registry, local=False, fix_versio   │
│   175 │   │                                                                                      │
│   176 │   │   if print_results:                                                                  │
│   177 │   │   │   self._print_results(show_passed=show_passed, sort_by=sort_by)                  │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/modules/lint/__init__.py:210 in lint_modules                  │
│                                                                                                  │
│   207 │   │   │                                                                                  │
│   208 │   │   │   for mod in modules:                                                            │
│   209 │   │   │   │   progress_bar.update(lint_progress, advance=1, test_name=mod.component_na   │
│ ❱ 210 │   │   │   │   self.lint_module(mod, progress_bar, local=local, fix_version=fix_version   │
│   211 │                                                                                          │
│   212 │   def lint_module(                                                                       │
│   213 │   │   self,                                                                              │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/modules/lint/__init__.py:278 in lint_module                   │
│                                                                                                  │
│   275 │   │   │   │   if test_name == "main_nf":                                                 │
│   276 │   │   │   │   │   getattr(self, test_name)(mod, fix_version, self.registry, progress_b   │
│   277 │   │   │   │   else:                                                                      │
│ ❱ 278 │   │   │   │   │   getattr(self, test_name)(mod)                                          │
│   279 │   │   │                                                                                  │
│   280 │   │   │   self.passed += [LintResult(mod, *m) for m in mod.passed]                       │
│   281 │   │   │   warned = [LintResult(mod, *m) for m in mod.warned]                             │
│                                                                                                  │
│ /Users/mitochondrium/tools/nf_core/modules/lint/environment_yml.py:86 in environment_yml         │
│                                                                                                  │
│    83 │   │                                                                                      │
│    84 │   │   if valid_env_yml:                                                                  │
│    85 │   │   │   # Check that the dependencies section is sorted alphabetically                 │
│ ❱  86 │   │   │   if sorted(env_yml["dependencies"]) == env_yml["dependencies"]:                 │
│    87 │   │   │   │   module.passed.append(                                                      │
│    88 │   │   │   │   │   (                                                                      │
│    89 │   │   │   │   │   │   "environment_yml_sorted",                                          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TypeError: '<' not supported between instances of 'dict' and 'str'
System information

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with nf-core modules lint doubletdetection and inspect the nested environment.yml shown in the issue and linked pull request 7399. Trace the modules lint entry point from the traceback, then verify that correctly formatted environment files containing pip dependencies complete linting without a traceback.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.