Opened 7 years ago
Closed 7 years ago
#1516 closed defect (fixed)
command-line breaks when a command is a prefix of another command (was: make install: '_Defer' object has no attribute 'function')
Reported by: | Tristan Croll | Owned by: | Greg Couch |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | Command Line | Version: | |
Keywords: | Cc: | Conrad Huang | |
Blocked By: | Blocking: | ||
Notify when closed: | Platform: | all | |
Project: | ChimeraX |
Description
I *think* this has been triggered because I defined a set of commands clipper xxx ...
for which the existing clip
command is a prefix. Anyway, when I run make app-install
I get, at the tail end of the build:
Executing: toolshed install './dist/ChimeraX_Clipper-0.2.1-cp36-cp36m-linux_x86_64.whl' unloading module chimerax.clipper Successfully installed ChimeraX-Clipper-0.2.1 Installed ChimeraX-Clipper (0.2.1) '_Defer' object has no attribute 'function' exit Unknown command: exit Unknown command: exit 100.00% done: Finished initialization UCSF ChimeraX version: 0.8 (2018-12-06) cmd>
With no traceback I have no idea where the offending _Defer.function
call is (I believe it should be replaced with ...proxy
), but adding the following to commands.cli._Defer
is a successful band-aid:
@property def function(self): return self.proxy
Attachments (3)
Change History (15)
comment:1 by , 7 years ago
Component: | Tool Shed → Command Line |
---|---|
Summary: | make install: '_Defer' object has no attribute 'function' → command-line breaks when a command is a prefix of another command (was: make install: '_Defer' object has no attribute 'function') |
comment:2 by , 7 years ago
Cc: | added |
---|---|
Owner: | changed from | to
comment:3 by , 7 years ago
Status: | assigned → accepted |
---|
comment:4 by , 7 years ago
Hi Tristan,
Could you send me the bundle_info.xml file for the Clipper bundle? I've found other bugs, but not that one yet.
-- Greg
comment:5 by , 7 years ago
And the bundle's init.py file please. Might be an interaction between them.
follow-up: 6 comment:6 by , 7 years ago
Here you go. I've also attached the cmd.py defining the commands. The line: <ChimeraXClassifier>ChimeraX :: Command :: cxclipper :: General :: Command-line control of Clipper plugin for symmetry and map visualisation</ChimeraXClassifier> was originally: <ChimeraXClassifier>ChimeraX :: Command :: clipper :: General :: Command-line control of Clipper plugin for symmetry and map visualisation</ChimeraXClassifier> ... with __init__.py and cmd.py changed to suit. Adding the 'clipper ...' commands triggered the bug, and renaming them to 'cxclipper ...' made it go away. Happy to send a full source tarball if you need it. On 2018-12-11 01:41, ChimeraX wrote:
comment:7 by , 7 years ago
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
Whatever you did, the problem appears to be gone in today's build. Clipper now builds without issue with commands named as clipper ...
. I notice that the warning that previously appeared in the bash shell (something along the lines of "'clip' command is a prefix of 'clipper'") is gone. What is the general consensus on this situation? "clipper" would certainly be the most natural top-level command to contain Clipper-specific commands, but I'm ok with switching over to something else (I was running with "cxclipper") if you prefer.
comment:8 by , 7 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
... or not. Not sure why it stopped happening for a while, but it popped up again. By forcing toolshed.info.register()
to raise errors rather than logging them as warnings, I was able to drill down closer to the issue (see traceback below).
There are actually two issues. The first, in core.commands.cli.add_subcommand()
is the source of the original "'_Defer' object has no attribute 'function'" error. In cli.register()
:
if isinstance(function, _Defer): cmd_desc = function else: cmd_desc.function = function if cmd_desc.synopsis is None: msg = 'Command "%s" is missing a synopsis' % name if logger is None: print(msg) else: logger.warning(msg)
... so something's not right there. The bigger issue, though, is in toolshed.info.register()
:
try: self._register_commands(logger) except Exception as e: logger.warning(str(e))
... so the ValueError
arising from the prefix clash only gets logged as a warning, but stops registration of all commands beyond that point. So, safe to say that it's *not* currently possible to have two registered commands where one is a prefix of the other. Will adjust my code accordingly.
NOTE: Traceback (most recent call last): File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 1894, in add_subcommand _check_autocomplete(word, self.subcommands, name) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 1709, in _check_autocomplete raise ValueError("'%s' in '%s' is a prefix of an existing command '%s'" % (word, name, key)) ValueError: 'clip' in 'clip' is a prefix of an existing command 'clipper' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/opt/UCSF/ChimeraX-daily/lib/python3.6/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/runpy.py", line 85, in _run_code exec(code, run_globals) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/ChimeraX_main.py", line 807, in <module> exit_code = init(sys.argv) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/ChimeraX_main.py", line 544, in init check_available=opts.get_available_bundles) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/__init__.py", line 1283, in init _toolshed = Toolshed(*args, **kw) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/__init__.py", line 341, in __init__ self.reload(logger, check_remote=check_remote, rebuild_cache=rebuild_cache) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/__init__.py", line 405, in reload self._installed_packages) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/installed.py", line 77, in register_all bi.register(logger) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/info.py", line 239, in register raise e File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/info.py", line 237, in register self._register_commands(logger) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/toolshed/info.py", line 268, in _register_commands cli.delay_registration(ci.name, cb, logger=logger) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 1839, in delay_registration register(name, None, _Defer(proxy_function), logger=logger) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 2003, in register _parent_info.add_subcommand(words[-1], name, cmd_desc) File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 1896, in add_subcommand if cmd_desc is None or not isinstance(cmd_desc.function, Alias): AttributeError: '_Defer' object has no attribute 'function' BUG: AttributeError: '_Defer' object has no attribute 'function' File "/opt/UCSF/ChimeraX-daily/lib/python3.6/site- packages/chimerax/core/commands/cli.py", line 1896, in add_subcommand if cmd_desc is None or not isinstance(cmd_desc.function, Alias): _See log for complete Python traceback._
comment:9 by , 7 years ago
Status: | reopened → accepted |
---|
To handle clip vs. clipper, we will turn it into a warning and we will register the standard commands first, so you won't see the warning.
comment:10 by , 7 years ago
Can reproduce by registering two commands in a bundle and the second one is a prefix of the first.
comment:11 by , 7 years ago
FYI, the symptoms are gone, and there are better warnings in the toolshed.info.register() code for cases when something does go wrong. The fix where was to not check if cmd_desc is not None, but that isinstance(cmd_desc, CmdDesc) before checking that the cmd_desc.function is an Alias or not.
The clip vs clipper issue still needs work.
comment:12 by , 7 years ago
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
clip vs clipper will be handled by having the standard commands bundle be a prerequisite so it is registered first. In the mean time, it will show up as a warning if clipper happens to be registered before clip.
Looks like I'm going to have to find a different front-end command than
clipper
... The previously-mentioned band-aid fix gets the build working again, but when I start ChimeraX the entire command system is broken: