Python plugin smproxy keyword arguments aren't working as expected

Why is the label argument to the smproxy decorator used to set the name of the source in the namespace and not the name argument?

For example, here is a very simple Python plugin:

from paraview.util.vtkAlgorithm import smdomain, smhint, smproperty, smproxy
import vtk
import vtk.util.vtkAlgorithm as valg

MENU_CAT = 'Test Category'

@smproxy.source(name='NameEarthSource', label='Label Earth Source')
@smhint.xml('<ShowInMenu category="%s"/>' % MENU_CAT)
class CustomEarthSource(valg.VTKPythonAlgorithmBase):
    """A simple data source to produce a ``vtkEarthSource`` outlining the
    Earth's continents. This works well with our ``GlobeSource``.
    def __init__(self, radius=6371.0e6):
                                             nOutputPorts=1, outputType='vtkPolyData')
        self.__radius = radius

    def RequestData(self, request, inInfo, outInfo):
        """Used by pipeline to generate the output"""
        pdo = self.GetOutputData(outInfo, 0)
        earth = vtk.vtkEarthSource()
        return 1

    @smproperty.doublevector(name="Radius", default_values=6371.0e6)
    def set_radius(self, radius):
        """Set the radius of the globe. Defualt is 6.371.0e9 meters"""
        if self.__radius != radius:
            self.__radius = radius

Then load that in the pvpython shell within ParaView:

Python 2.7.16 (default, Apr 17 2020, 18:29:03) 
[GCC 4.2.1 Compatible Apple LLVM 11.0.3 (clang-1103.0.29.20) (-macos10.15-objc- on darwin
>>> from paraview.simple import *
>>> LoadPlugin('/path/to/', ns=globals())

and then the name of the filter is given by the label string rather than the name string:

>>> LabelEarthSource
<function CreateObject at 0x12d036050>

This is counter to what I would have thought as the label is what appears in the UI all nice and pretty-like. Also, this is inconsistent with the documentation found on:

  1. name: if present, provides the name to use of the Proxy. This is the name that ParaView uses to refer to your class. If none specified, the name is deduced from the class name.
  2. label: if present, provides the label to use in the UI. If missing, the label is deduced from the name.
  3. class: if present, is the fully qualified class name ParaView should use to instantiate this object. Except for exceptional situation, it’s best to let ParaView deduce this argument.
  4. group: if present, is the proxy-group under which the definition must be placed. This is often not needed since the decorators set a good default based on the role of the proxy.

On this note, class is a totally invalid keyword argument and yeilds a syntax error:

>>> # Generally, this is illegal in Python
>>> def foo(class=5):
...      pass
SyntaxError: invalid syntax

so this should be changed:

Indeed, label is used in scripts not name. The reason is that one can use in scripts the strings he sees in the interface instead of something that is hidden.

I had the same question when I started. I would set both name and label to the same string.


1 Like

Thanks, @danlipsa! That’s the direction I was heading and your point:

The reason is that one can use in scripts the strings he sees in the interface instead of something that is hidden.

Totally makes sense.

Simple workaround, but at least this is documented for the next person

An important consequence of using labels in Python is that labels should be chosen very carefully, because changing them requires taking steps the ensure backwards compatibility. It’s possible, but always adds a cost.

1 Like

Additionally, it’s generally a good idea to keep the name and the label the same except for difference in space or case.