Autocomplete while editing python scripts outside of Rhino

It doesn’t look like PyCharm is recognizing your installation of Rhino stubs. You might need to look at you PyCharm project settings to see if the package is installed.

The stubs are just there to assist with autocomplete so it doesn’t matter much if you are focused on V6 or V7 work.

@Willem can you try in Pycharm:

import Rhino.Geometry as rg

image

does that work?

Hi David,

That is indeed working and was my point, but I see that was not clear:

image

image

I’d rather not have to import all Rhino namespaces individually

EDIT:
I though this was related to the Rhino Namespace but any ‘sub’ will not autocomplete:
image

-Willem

Hi @stevebaer and @DavidLeon

After some digging and testing I found that this is expected behavior and the auto-completion like in the Rhino Python Editor is not.

However I did find a solution in defining an __all__ in the __init__.pyi files.
For that I wrote the script below to be run in the Rhino-stubs root.

import os

start_dir = os.path.dirname(__file__)

for root, dirs, files in os.walk(start_dir ):
    
    init_files = [f for f in files if os.path.basename(f) == '__init__.pyi']
    if init_files and dirs:
        
        str_dirs = ["'{}'".format(dir) for dir in dirs]
        
        all_str = '__all__ =['
        all_str += ','.join(str_dirs)
        all_str += ']\n'
        
        #assume single __init__.pyi per directory
        init_file = os.path.join(root,init_files[0])
        with open(init_file, 'r') as file:
            init_data = file.read()
        
        #ignore existing '_all__'
        if init_data.startswith('__all__ =['):
            lines = init_data.split('\n')
            init_data = '\n'.join(lines[1:])
            
        new_init_data = all_str + init_data
        
        with open(init_file, 'w') as file:
            file.write(new_init_data)
        

__init__.pyi files now look like this:

__all__ =['ApplicationSettings','Collections','Commands','Display','DocObjects','FileIO','Geometry','Input','NodeInCode','PlugIns','Render','Runtime','UI']
from typing import Tuple, Set, Iterable, List


class RuntimeEnvironment:
    Unset = 0
    #None = 1

And autocompletion in pycharm is working like so:
image
image

I’m not sure how harmful it is to add the __all__ declaration to the stubs but I suppose it’s not.
I’m going to run the script above over my own module structure to have this type of autocompletion for those as well.
-Willem

2 Likes

Interesting; I could definitely add this to the pyi files if it helps. Play with it for a bit and let me know if it continues to work as expected. We’ll also need to test this in VS Code to make sure it doesn’t break anything there.
Thanks Willem

1 Like

@eirannejad do you have any experience with using the __all__ syntax in the pyi files? I’m looking to update the stubs with the latest set of RhinoCommon changes and was wondering if I should tackle this at the same time.

I have used __all__ in python modules but not in .pyi files. It should be fine tho. It basically controls what is exported from a module. Let’s add and test in VSCode.

@Willem Out of curiosity, does the auto-complete feel faster after the addition of __all__?

Sounds good, I’m tweaking the stubbler application to include __all__ when generating the stubs. I’m also adding some functionality to skip methods marked as Obsolete in .NET so you get a better autocomplete list.

Ok; I updated the packages on PyPi.org. See if these new ones work for you. If they don’t I can adjust and upload a different version

@stevebaer: I’m trying out visual studio code with this. I am trying to mimic importing scriptcontext as I haven’t found a way to do this with the stubb module alone, so I am making a scriptcontext.py living in the project folder. I’m mostly just after the doc object and it’s tables, so the file content is simple:

import Rhino

doc = Rhino.RhinoDoc()

Then in the script I can do the regular import:

import scriptcontext as sc 

Which will also work when hosted in Rhino.

However, VSCode doesn’t seem to pick up the tables of the doc. In the __init__.py file, the Rhinodoc class has these as properties (the object table for example):

@property
def Objects(self) -> ObjectTable: ...

But (at least my) VSCode doesn’t know what an ObjectTable is so the return type is lost. I found that if I import Rhino at the top of __init__.py, and then put the return type as:

@property
def Objects(self) -> Rhino.DocObjects.Tables.ObjectTable: ...

Then VSCode is auto-completing the object table in my script.

Do you think this could be included in the stubb generator for all Rhinodoc tables (or maybe all Rhino return types, I don’t think VSCode knows what any of them are)?

Thanks.

Nathan

Hi, there is a question that are there any ways to use pycharm for editing RhinoPython and keep pycharm and rhino interlocked?

hi @stevebaer @eirannejad, It´s been a while since I use the stubs… are they supposed to work with the latest versions of python? I can´t manage to get any autocomplete in VS Code with ver 3.9. If not, which version do you recommend I use? Thanks!

1 Like

Hey David; I also haven’t touched this library for a long time. They should work with 3.9

I can confirm that I cannot get autocompletion to work in VSCode. Current anaconda 3 (python 3.8.5), Rhino-Stubs installed but not working unfortunately.

edit: could it be that the stubs are not using the right syntax for VSCode ?
see List comprehension in __all__ definition hides module members · Issue #289 · microsoft/pylance-release · GitHub
by renaming the folder from “Rhino-Stubs” to “Rhino” and editing the __init__.pyi to include

from .Geometry import *
from .Collections import *
from .Commands import *
from .Display import *

etc…
before the line
__all__ = ['ApplicationSettings','Collections','Commands','Display','DocObjects','FileIO','Geometry','Input','NodeInCode','PlugIns','Render','Runtime','UI']

I got autocompletion to work. Seems like these files need to be updated or I don’t get it. I don’t know if this is a clean solution or not as I am literally just starting out using VSCode and Python.

Thanks for your help!

1 Like

@stevebaer I have successfully loaded Rhino/GH python stubs in VSCode by doing a few minor tweaks.
Check out branch: /fixed-stubs-for-vscode-RH_7.2.21012
Hope it helps everyone

Issues-Causes:

  1. Empty classes cause an issue and prevent loading of the entire stub file
  2. VS Code does not detect folders with postfix -stubs, as confirmed by @matthias2

Solution:

  1. Add “pass” to empty classes
...
class SurfaceProxy(Surface):
    pass # added for empty classes


class SweepOneRail:
    def __init__(self): ...
...
  1. Remove postfix in build script.
  2. Once done, add those paths into “python.analysis.extraPaths
"python.analysis.extraPaths": [
    "pythonstubs\\stubs\\Eto",
    "pythonstubs\\stubs\\GH_IO",
    "pythonstubs\\stubs\\GH_Util",
    "pythonstubs\\stubs\\Grasshopper",
    "pythonstubs\\stubs\\Rhino"
]
4 Likes

Usually I import them individually to make the autocomplete work without modifying the stubs.
At least until the stubs files gets an update :slight_smile: @stevebaer

import Rhino
import Rhino.Geometry # child namespace
import Rhino.Commands # child namespace
import Rhino.Display # child namespace
import Rhino.Collections # child namespace

I’m not sure what is the best solution to this, but the autocomplete doesn’t seem to pickup the namespaces inside __all__ in VS Code

I found that it works in VS Code by importing submodules in __init__.py files:

from . import <childnamespace>
2 Likes

Thanks Tony, I’ll try to take a look at your github pull request on this soon

2 Likes

Hello,

It is possible to complete Rhino3dm’s PYI, more exactly all iterable objects break type annotations.
Such as File3dmObjectTable or Iterable[...]
jmv

@stevebaer I wanted to add to this thread to say that I’ve also successfully started using the stubs in Sublime Text 4. Thanks for making the stubs!

For anyone else who wants to use Sublime Text:
Steps are:

  1. Install Sublime Text 4 (This is an amazing text editor, but it doesn’t have python autocomplete out of the box)
  2. From inside Sublime text, install the Sublime Text Package Manager (This is an installation utility that allows you to acquire a package that does autocomplete)
  3. Install the Sublime Text Anaconda Package (Anaconda has autocomplete for python… but don’t be confused. This is not the same thing as the Anaconda Python distribution).
  4. Now test that autocomplete works for standard python. For example type the following:
testList = ['foo','ham','eggs']
test.a

You should see ‘append’ as a suggestion because testList is a list. You will not yet be able to get autocomplete for Rhino Common though…for this I needed to get the stubs Steve made.

Edit: Note, when setting this up on a new machine the autocomplete did not work until I had installed Python 2.7.16 and then restarted the machine. So, if the autocomplete is not working yet, just continue until step 3 in the following list!

To get the stubs:

  1. Install python 2.7.16
  2. Add C:\Python27 to the system path variable
  3. Add C:\Python\Scripts to the system path variable
  4. Open the command line
  5. run ‘python -m pip install Rhino-stubs’ ( more info here Rhino-stubs · PyPI)
  6. In the Sublime Text Menus, go to project / Add folder to project…
  7. Select the folder that contains the Rhino stubs, for me this was:
    C:\Python27\Lib\site-packages\Rhino-stubs

To get Rhino script syntax to autocomplete:

  1. In the Sublime Text Menus, go to project / Add folder to project…
    2.Add this folder, but you’ll need to change the username, and the number in parenthesis after IronPython will also change: C:\Users\Alexanderj\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib

Autocomplete is working for Rhino common:

Some notes on what didn’t work:
I tried to get this to work with Jedi alone because at first glance Jedi appeared to support Python 2.7:

However using Jedi 0.18.0 I got nothing but errors, mostly Lookup errors and type encoding errors that suggested the python versions weren’t compatible.

… then I spotted a note in the Anaconda python package for Sublime Text saying that Jedi is dropping support for Python 2.7.

(Anaconda turns your Sublime Text 3 in a full featured Python development IDE including autocompletion, code linting, IDE features, autopep8 formating, McCabe complexity checker Vagrant and Docker support for Sublime Text 3 using Jedi, PyFlakes, pep8, MyPy, PyLint, pep257 and McCabe that will never freeze your Sublime Text 3 | PythonRepo Releases(v2.2.0)/ )) …

Next I realized Jedi is the autocomplete that ships with the Sublime Text Anaconda package. (Don’t be confused with the homonymous Anaconda python distribution, Anaconda is installed through the package manager in Sublime text.)

So, it looks like this solution will be deprecated after the next release of the Anaconda package, but at least it works for the moment.

4 Likes

Also, here is how to set up a Grasshopper canvas to run a python file created in Sublime. Just point the PathToPython file path to the python file on your disk by right-clicking the path and say ‘select one file’.

Note that the File component needs to be set to ‘Total File’, so leave ‘Per Line’ unchecked, as below:
image

Right-click on the ghPython component and select ‘Show Code Input Paramter’ to expose the correct input.

TestPythonRunCode.gh (8.7 KB)

2 Likes