Invoke: auto_dash_names setting is ignored

Created on 2 Aug 2017  路  7Comments  路  Source: pyinvoke/invoke

Using invoke version 0.20.1.

./invoke.yaml and ~/.invoke.yaml:

tasks:
    auto_dash_names: false

./tasks.py:

from invoke import task


@task
def my_awesome_task(c):
    print("Awesome!")

Per the documenation, I would expect this to work, but it does not:

$ inv my_awesome_task
No idea what 'my_awesome_task' is!

Using dashes in the name does work, though:

$ inv my-awesome-task
Awesome!
Bug

Most helpful comment

It's on PyPI!

All 7 comments

Strange, I know I tested that before I published, clearly something's gone sideways. Will look into it ASAP. Thanks for the report!

Yup, my goof. Had all the plumbing set up, and tested, but never tested or implemented that critical bridge between the CLI machinery and the task collection, so "config says no auto dashes -> tell collection not to emit auto-dashed names" never occurs. Fixing now.

Related, this has caused issues with the fabric's test suite since the task names are now dasherized. As a temp fix, I tried adding auto_dash_names=False to its task collection.

ns = Collection(
    docs, www, test, coverage, integration, sites, watch_docs,
    watch_tests, count_errors, release, travis,
    # TODO: update tests and travis.yml to use dasherized names
    auto_dash_names=False,
)

Running inv --list raised the following exception:

Traceback (most recent call last):
  File ".venv/bin/inv", line 11, in <module>
    load_entry_point('invoke==0.20.1', 'console_scripts', 'inv')()
  File ".venv/lib/python3.6/site-packages/invoke/program.py", line 287, in run
    self._parse(argv)
  File ".venv/lib/python3.6/site-packages/invoke/program.py", line 357, in _parse
    self.parse_tasks()
  File ".venv/lib/python3.6/site-packages/invoke/program.py", line 522, in parse_tasks
    contexts=self.collection.to_contexts(),
  File ".venv/lib/python3.6/site-packages/invoke/collection.py", line 337, in to_contexts
    task = self[primary]
  File ".venv/lib/python3.6/site-packages/invoke/collection.py", line 285, in __getitem__
    return self.task_with_config(name)[0]
  File ".venv/lib/python3.6/site-packages/invoke/collection.py", line 322, in task_with_config
    return self.tasks[name], ours
  File ".venv/lib/python3.6/site-packages/invoke/vendor/lexicon/alias_dict.py", line 80, in __getitem__
    return self._handle(key, None, single, multi, unaliased)
  File ".venv/lib/python3.6/site-packages/invoke/vendor/lexicon/alias_dict.py", line 62, in _handle
    return unaliased(self, key, value)
  File ".venv/lib/python3.6/site-packages/invoke/vendor/lexicon/alias_dict.py", line 74, in unaliased
    def unaliased(d, key, value): return super(AliasDict, d).__getitem__(key)
KeyError: 'watch-docs'

Hooking that stuff up exposes another hidden issue, hooray! (Note to self...)

  • The Collection created by Loader gets the flag OK now
  • However, explicit collection modules (ones which define a ns = Collection(...)) are problematic - because _they_ are created in a vacuum and don't have access to the config, _they_ still get the default auto-dash behavior, even if Collection.from_module ends up "cloning" them into a new Collection that _is_ honoring the config.
  • Thus, the "inner" collection's data structures all still exhibit dashed names, even if the "outer" one has dashes disabled; and thus the copied structures also have dashed keys.
  • This causes a symptom where trying to call Collection.to_contexts() (for parsing) dies:

    • it's iterating over .task_names (which honors task name transformation, and thus underscores any dashes) and then looking up the resulting names within itself.

    • but because its __getitem__ doesn't do transformation, and holds the dashed versions of names emitted from the "inner" config, this turns into an attempt to look up, say, foo_bar (honoring config) in a dict/lexicon whose keys only contain foo-bar (default behavior)

  • In non-cloning behavior, this isn't an issue because name transformation is applied in add_task and add_collection, so "normally" there's no way to end up with this mismatch.
  • Thus the right solution _seems_ like it should be to apply transforms during cloning, even though that may be a PITA (right now cloning gets away with a simple deepcopy.)

@rpkilby That's exactly the issue I'm fixing right now, yup :)

Works for me now, making sure Travis agrees, then will release as 0.20.2 :)

It's on PyPI!

Was this page helpful?
0 / 5 - 0 ratings