GHPython Default Type Hint

Hi @piac,

This is something that’s kinda been bothering me for years, but have never really thought to bring up: Seeing as how I prefer to almost always develop GHPython component using No Type Hints, and the default type is:

I’m going through this sub-menu quite a lot during the day. Would it be possible to have the default be No Type Hint or perhaps being able to set a default on a per user basis?

Best,

Anders

3 Likes

Hello,

That would be useful.
It’s logged here.

Thanks

3 Likes

Brilliant, cheers Alain :raised_hands:

or defined inside the code

You can already do that by getting the input params and setting their properties within the script. That was not really the point I was getting at though (i.e. to hit the GHPython/RhinoCommon ground running with minimal manual fiddling/clicking/typing).

Just wanted to gently bump this :wink:

I’m still rather hugely annoyed by this unfortunately!

You can easily fix this by creating a User Object that is the predefined version of GhPython that you want.

For example, you can set its type hints, default code, its default input number and names, default Guid output, default icon, really anything that you can customize and save… Then you can name it, and create a User Object with that single component. It will browse just normally with your name and will be easy to use instead of the plain version.

I hope this helps,

Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

1 Like

I appreciate this idea, I really do. But I wouldn’t consider it a fix, as input parameters that are added via ZUI will still default to the default type hint (I believe, pretty sure, on my phone).

In my experience during GHPython development, parameters come and go, are moved around, are renamed etc. as one gets closer and closer to understanding and structuring the problem and it’s solution. This is in fact one of the things that make GHPython my favourite RhinoCommon “IDE”. But having to grab the mouse and hover/click through this cumbersome menu and set type hints to off every single time, really breaks this otherwise fast and agile development flow. Which is a real shame IMO :slightly_frowning_face:

1 Like

Yeah, I see that part. I don’t think this will work well for anyone using RhinoScript, though. So it would be a pity, making someone less happy and more confused. Imagine all the tutorials that need to change… Also, as usual, I don’t want to add options for such small things; I think this could be fixed by copying the “Hint” style of a neighboring input. Only if all inputs go away, then the “overall” default is picked.

Reported as RH-54143.

That’s a really good idea.

And I can certainly understand not wanting to break things or cause confusion. That said, I also don’t believe adding functionality (or even fiddling with an xml) for setting the default type hint locally on one’s system would do that.

Again, I’m not asking that you change the default type hint for everyone. I’m just asking for the option to set it locally to my personal preference. Everybody wins :raised_hands:

This was earlier translated to a too drastic move: https://mcneel.myjetbrains.com/youtrack/issue/RH-46635

I think you lost me. I agree that changing the default type hint is too drastic. But surely adding functionality that enables one to change it on a per user basis to ones preference isn’t?

1 Like

Any option added has an implicit high cost of testing and maintaining it with any other option. (What happens if the name of hints changes, if we need to move hints, how do we keep track of the hints that you have to set in the option editor and what is the 1-to-1 reference with the list, for example if you write giuds, what will the editor do… etc etc). All this costs really a lot of time.

I think this particular one will be best solved with the copying strategy for now. With that change, we will see if it is enough or it will need more tweaks.

I can appreciate that. But I guess I just don’t see how adding an option to set a default type hint locally by user preference would have such severe implications/high cost.

That sounds good. I’ll take it :beers:

On a side note (might help others), I added this function to my GHPython development utility functions module. Which I sometimes use to turn type hints off locally within one component, especially if I’m adding multiple inputs straight off the bat:

import GhPython

def setNoTypeHint(ghenv):
    
    """ Set all input parameters to No Type Hint, might throw expired during solution when first ran """
    
    for v in ghenv.Component.Params.Input:
        v.TypeHint = GhPython.Component.NoChangeHint()
    ghenv.Component.ExpireSolution(False)
1 Like

Hi @AndersDeleuran,

As a newcomer to Python scripting in Grasshopper, may I ask you for an example of what you put in your scripts to replace the functionality provided by the type hinting? So far I’m using the hinting but would prefer not to…

Thanks
Jeremy

Most objects will pass along as exactly what they are (use type() inside the script to check). But some might surprise you (for instance an integer will pass as a float, and a polyline will pass as a polylinecurve etc). In such cases I simply cast them to whatever the code expects (typically in the outer scope of the code) when they are first called. For primitive data types you can use for instance int(nameOfVariable) to cast to an integer. For RhinoCommon types you’ll need to use whatever the relevant case is, for instance somePolylineCurve.TryGetPolyline().

To document this I’ve iteratively developed this structure over the years, which makes explicit within the code what input parameters are expected, their Access type, and the object type:

I automate the generation of these docstrings using this function:

import Rhino as rc
from datetime import date

def buildDocString(ghenv):
    
    """ Builds a documentation string by iterating the component
    (i.e. ghenv.Component) input and outputs parameters """
    
    ds = "Write main component documentation here.\n"
    ds += "    Inputs:\n"
    for v in ghenv.Component.Params.Input:
        ds += "        " + v.Name + ": {" + str(v.Access).lower() + "," + str(v.TypeHint.TypeName).lower() + "}\n"
    ds += "    Outputs:\n"
    for v in ghenv.Component.Params.Output:
        ds += "        " + v.Name + ": \n"
    ds += "    Remarks:\n"
    ds += "        Author: Anders Holden Deleuran (BIG IDEAS)\n"
    ds += "        Project:\n"
    ds += "        License:\n"
    ds += "        Rhino: " + str(rc.RhinoApp.Version) + "\n"
    ds += "        Version: " + str(date.today()).replace("-","")[2:] + "\n"
    
    print ds
    return ds

Note that it currently doesn’t fill out the object type (but it should, and probably will at some point). Edit: oh wait, I actually did add this. But using the type hint to document the type. So without type hint, this will simply be set to system.object.

6 Likes

Hi Anders,

Thanks for the generous, speedy and helpful reply.

Jeremy

1 Like

This is actually not correct. Only floats-that-look-like-integers will pass as floats, which is what they are. Just like strings-that-look-like-numbers will pass as str. Except if you set a specific Hint.

This is also not entirely true.

image
Grasshopper generally returns Polylines as curves, and therefore PolylineCurves, but strictly speaking it would not be obliged to. It’s a decision by David to make geometry always derive from GeometryBase for particular needs.

It’s just much easier to use TypeHint => Polyline, and all the Grasshopper-specific conversions that are required to work to make your script fully compatible with Grasshopper will be given to you, free of charge. It’s actually not sufficient to call PolylineCurve.TryGetPolyline() to fully support all polyline conversions.

Somebody might come up with some geometry type that has no Rhino.Geometry.Curve representation, but that might have a good polyline counterpart. For example, some type of Graph. In that case, their underlying type might not have a TryGetPolyline() method, but would still be convertible if you just used the correct Hint.

This being said, I think this conversation has already lasted overly long. Many more times than you think, scripts with No type Hint are not fully compatible with Grasshopper and become somehow impaired versions of normal components. For example, try inputting a Polyline where a No type Hint script expects a float. Does it work, by computing the curve length? If not, the No type Hint strategy will make your script not on-par with the general Grasshopper standard and, if the script is not only meant for you, it will make it just less robust.

You mention you are a newcomer to Python scripting in Grasshopper. As explained above, this is only sometimes a great decision. Please analyze case-by-case if this strategy is best suiting all your needs, including especially compatibility with the generous Grasshopper automatic conversion system.

Sorry, I should have said some integers (like the ones from an integer slider), and some polylines (like the ones from the PolyLine component).

Right, this whole what-type-is-thing-when/type conversion hoopla I personally find frustrating and needlessly complex. What does “look-like” even mean? It doesn’t seem very explicit nor beginner-friendly IMO. I prefer to simply pass things, check their type() and act accordingly. That might not make for the most robust/generic Grasshopper components (but hey, at least they’ll be very explicitly documented in terms of what inputs expect to be passed), but that’s not my intention. It’s to solve design problems as fast and agile as I can. If my intention was to write “real” components I’d be in Visual Studio, following the standards devised by David.

My point is that these pipelines ARE precisely meant for me and my organisation. And as such follows the development standards I’ve been using over the years. Which would benefit from not using type hints. As a customer and longtime user I’m honestly a bit bummed that this doesn’t appear to carry much weight. It’s starting to feel like there’s only one sanctioned McNeel way of using GHPython (i.e. using rhinoscriptsyntax with type hints). Which is a real shame, considering precisely how flexible and agile it in fact is. like, I freaking love the thing right!

4 Likes

They are not integers… This is exactly why Hints exist. Maybe you just do not like the name. In fact, it should rather be “Automatic conversion to”, probably.

I hear you, but welcome to computing.

We try to accommodate new users of GhPython who come from Rhino, and those who never scripted, and also long-standing users. Not always the three groups have a lot in common. At best, all of them would feel at ease writing great scripts with minimal effort.