robotcodedev / robotcode

RobotFramework support for Visual Studio Code
https://robotcode.io
Apache License 2.0
176 stars 14 forks source link

[BUG] Initializing library 'XYZ' with no arguments failed #100

Closed jura84 closed 1 year ago

jura84 commented 1 year ago

Describe the bug When trying to import own custom library which requires arguments, API documentation generation fails.

We are using dictionaries which are passed to libraries. Dictionaries can be used to configure library based on the needs. image

This is solved in Robocorp plugin like this. Where you list all custom python libraries to LibDoc which arguments needs to be passed when generating documentation. Not sure is this right way to do this. IMHO all libraries should pass all arguments to LibDoc.

image

To Reproduce Steps to reproduce the behavior:

  1. See code example from here: https://github.com/robocorp/robotframework-lsp/issues/804

Expected behavior API documentation generated to all custom python libraries defined in python path without explicitly have to configure which libraries needs special configuration.

Desktop (please complete the following information):

Additional context Ask more information if needed.

d-biehl commented 1 year ago

What error message do you get during library import?

Normaly these errors happens at library import because the design of your library constructor is not optimal. RobotCode (also Robocorp LS) tries to call the RobotFramework tool libdoc internally, libdoc tries to instanciate the library and then ask for the methods that should be keywords for robot. If it cannot instanciate the library, for whatever reason, libdoc cannot get these keywords.

A good constructor for a RobotFramework library has optional parameters and fully initialize the library only if robotframework is running. In libdoc mode there is no test running.

Try to change you libraries like in this example:

from typing import Dict, Optional
from robot.running.context import EXECUTION_CONTEXTS

class DummyDevice:
    def __init__(self, device_config: Optional[Dict[str, str]] = None) -> None:
        if EXECUTION_CONTEXTS.current is not None:  # check if robot is running
            self.device = device_config.get("AA")

    def connect(self):
        print(f"device {self.device} connected")

    def disconnect(self):
        print(f"device {self.device} disconnected")

This is not really documented, but it prevents you from getting these errors.

Hope this helps a little bit.

jura84 commented 1 year ago

Yes, I understood what you said that Libdoc is used by these tools, and it tries to instanciate the library and then fetches all methods with documentations.

I was able to solve the issue by adding default values when accessing dictionary using get method. self.ip_addr = device_config.get("AA", "default-value")

The error which still exists is strange because the robot dictionary variable what error refers to is defined below in 'variables' section after Settings section.

image

Just like in the example below when giving ${DICTIONARY-EXAMPLE} variable to library.

image

Any idea why this variable is not visible to plugin / libdoc?

d-biehl commented 1 year ago

does this error occur right after editing the library import and disappear when you restart vscode? Or is it always there?

I can't reproduce this. Except for a small error when updating, if the line with the import already contained an error. But this can be resolved with restart/reload vscode.

Can you give me a more detailed example?

Btw. You use a - character in your variables. Unfortunately RobotFramework allows special characters in variable names. But something like this can easily lead to confusion. If the variable name contains characters that are not letters, numbers, spaces and underscores, RobotFramework tries to evaluate this as an expression and it can then lead to unexpected behavior or errors.

Maybe this is also the reason?

jura84 commented 1 year ago

Thanks for the comments. I found the issue.

I created simpler example which should present the whole issue.

I tried to init one of the variables based on the env vars which was not defined in any configurations or in PC env variables. The problem was the Robot Code did not indicate error on this one.

When I fixed this highlighted variable, I had to restart whole VS code to get this error appear or disappear. Seems that VS Code restart required always when this error appears.

See example below. image

So, seems that it fails to fetch env variable when using % character but IDE is not indicating anything and rest of variables are not created. That's why IDE says: image

So, I assume this is a bug that IDE did not indicate error on this one? When env var added into settings.json then it works OK.

image

However, plugin itself is working more or less fluently. Some slowness here and there and I have to restart VS code to get plugin working fluently. Thank you for your comments, those are highly appreciated! 👍

d-biehl commented 1 year ago

Thank you for your feedback ;-)

I published a new release of RobotCode where I implemented the analysing of missing Environment Variables. Can you try this version if it now works as you excpect?

jura84 commented 1 year ago

Yes now it works. image

However when I change it back it sees the env variable value but library still is underlined with red and indicates original error. image

Error: image

Error disappears when restarting VS Code. Can this be automated in the way that it reloads file check e.g., when saving the file?

d-biehl commented 1 year ago

This is a problem I am working on and will be fixed hopefully in the next version. So, be patient.

jura84 commented 1 year ago

OK. This problem is now solved.

The issue was that variables couldn't be initialized because it tried to set the first variable value using % character (from env variable) and it didn't work because env var wasn't there. Plugin didn't indicate any errors on missing env var.

Now this indication is fixed in new version.

likair commented 1 year ago
 if EXECUTION_CONTEXTS.current is not None:  # check if robot is running

This is a nice hack, where could I find the reference for this?

d-biehl commented 1 year ago

That is not really documented, but you can find some examples in the net, and you can look at the source code of robotframework like here https://github.com/robotframework/robotframework/blob/15e11c63be0e7a4ce8401c7d47346a7dc8c81bf5/src/robot/libraries/BuiltIn.py#L61