Skip to content

Applying attributes #567

Closed
Closed

Description

@r0x0r

Is it possible to apply attributes in pythonnet? In particular I would like to apply the System.Runtime.InteropServices.ComVisibleAttribute to a form.

Activity

  1. den-run-ai commented on Nov 2, 2017

    @den-run-ai
    Contributor

    @r0x0r this looks like not possible, since attributes cannot be added at runtime in .NET:

    https://stackoverflow.com/questions/129285/can-attributes-be-added-dynamically-in-c

    There was something flaky done in ironpython with clrtype metaclass, but it is in dark corners:

    http://www.voidspace.org.uk/ironpython/dark-corners.shtml#net-attributes-and-the-clrtype-metaclass

    https://stackoverflow.com/questions/359933/how-can-i-add-attributes-to-methods-and-types-defined-in-ironpython

    But @filmor and @dmitriyse definitely understand this better!

  2. dmitriyse commented on Nov 3, 2017

    @dmitriyse
    Contributor

    @r0x0r, do you want to apply C# attribute to python object and pass this object to some CLR code ?
    If so, than pythonnet should be greatly enhanced, it's very expensive feature. For each python object with CLR Attributes pythonnet under the hood should subclass PyObject in a dynamically generated assembly.
    And even in this case your all CLR attributes for your python object should be defined all at once.

    Probably you need some workaround - create your type with attributes in C# and use it in python.

  3. r0x0r commented on Nov 4, 2017

    @r0x0r
    Author

    Thanks for your responses. My use case is to pass a Python object to the WebBrowser.ObjectForScripting property. https://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting(v=vs.110).aspx
    The property requires for its value to be visible to COM via the ComVisible attribute. Defining a base class with the set attribute in .NET and inheriting it in Python does not help either, as a subclass must have the attribute set as well. Interestingly enough pythonnet does not throw an ArgumentException as in .NET, but fails silently and allows to call methods defined in the parent class, but not the subclass.
    Any advice how this issue can be circumvented?

  4. den-run-ai commented on Nov 4, 2017

    @den-run-ai
    Contributor

    Instead of base class, in C# you can define an interface and implement in Python, according to this article for this exact same problem:

    https://blogs.msdn.microsoft.com/srivatsn/2008/05/09/accessing-ironpython-objects-from-native-javascript/

  5. r0x0r commented on Nov 5, 2017

    @r0x0r
    Author

    Thanks, that did the trick. All the methods must be defined in advance in the interface, but at least it works. For a reference, here is the code I am using as the IronPython code in the link does not work verbatim.

    Interface

    namespace WebBrowserInterop {
        public interface IWebBrowserInterop
        {
            object call(string message, object param);
        }
    }
    

    Python code

        class JSBridge(IWebBrowserInterop):
            __namespace__ = 'JSBridge'
            def call(self, message, param):
                print(message, param)
                return 'value' # the value is returned to JS
    

    By the way it took me a while to figure out the namespace the class variable is required in order to inherit a C# interface in pythonnet. It would help if this was documented somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions