Skip to content

Constructor executed twice when overriding constructor in System.Object. #495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
klasma opened this issue Jun 15, 2017 · 3 comments
Closed

Comments

@klasma
Copy link

klasma commented Jun 15, 2017

Environment

  • Pythonnet version: 2.3.0
  • Python version: 2.7.13
  • Operating System: Windows 10

Details

We are trying to create a subclass of System.Object (using namespace) and override the constructor.

For some reason, the conctructor is executed twice when an instance of the class is created. Below is an example that reproduces the problem.

class X(System.Object):
    __namespace__ = "PyTest"

    def __init__(self):
        print("Running X constructor")

x = X()

The output is

Running X constructor
Running X constructor
@rickardraysearch
Copy link
Contributor

rickardraysearch commented Jun 15, 2017

Furthermore, if you add arguments to the constructor, the arguments are only passed the second time.

class X(System.Object):
    __namespace__ = "PyTest"

    def __init__(self, *args):
        print("Running X constructor, args = {0}".format(args))

x = X(1,2)

produces the output

Running X constructor, args = ()
Running X constructor, args = (1, 2)

It seems that the first invocation is from the call in Python.Runtime.MetaType.tp_call to tp_new, whereas the second invocation is from the call to py__init__ using Runtime.PyObject_Call.

Is the error that somehow the call to tp_new also ends up calling __init__?

@filmor
Copy link
Member

filmor commented Jun 16, 2017

Hmm, the comment says

    /// Metatype __call__ implementation. This is needed to ensure correct
    /// initialization (__init__ support), because the tp_call we inherit
    /// from PyType_Type won't call __init__ for metatypes it doesn't know.

Maybe this changed in Python? I'll have a look.

filmor added a commit to filmor/pythonnet that referenced this issue Jun 16, 2017
This seems to be a patch for broken behaviour in Python. Removing it
should solve pythonnet#495 (`__init__` called twice on construction).
filmor added a commit to filmor/pythonnet that referenced this issue Jun 16, 2017
This seems to be a patch for broken behaviour in Python. Removing it
should solve pythonnet#495 (`__init__` called twice on construction).
filmor pushed a commit that referenced this issue Jun 26, 2017
* Add tests of subclassing with __namespace__

* Remove __init__ call from ClassDerived.InvokeCtor

* Trying out __init__

* Cleanup

* Add tests constructing python type from CLR and calling __init__

* Revert borked changelog update

* Don't leak init reference

* Rename tests

* Remove unused internal Runtime.GetBoundArgTuple

* Reenable skipped tests in test_subclass.py
@filmor
Copy link
Member

filmor commented Jul 11, 2017

Fixed by #503.

@filmor filmor closed this as completed Jul 11, 2017
testrunner123 pushed a commit to testrunner123/pythonnet that referenced this issue Sep 22, 2017
* Add tests of subclassing with __namespace__

* Remove __init__ call from ClassDerived.InvokeCtor

* Trying out __init__

* Cleanup

* Add tests constructing python type from CLR and calling __init__

* Revert borked changelog update

* Don't leak init reference

* Rename tests

* Remove unused internal Runtime.GetBoundArgTuple

* Reenable skipped tests in test_subclass.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants