0

I'm working on generating a sample XML out of a subset of XSD schema file. I have generated data objects using GenerateDS. I instantiated the parent object and I'm using recursion with reflection to fill in all the children objects so I can write out an XML of this parent object and all of its children. Later, I want to fill in all the data attributes with test data to create my test XML.

I'm having a problem with the code GenerateDS generated out of my XSD. I'm not sure if it's my lack of understanding of object oriented programming in Python or if it's an issue with the library and maybe someone can help me with that. Here's the issue. When I run the export method, it executes self.exportChildren(outfile, level + 1, '', namespacedef_, name_='requestHeaderType', pretty_print=pretty_print) and passes file object into outfile and level is at 0 + 1 but the problem is that when exportChildren executes, and here are the parameters, self.Header.export(outfile, level, namespaceprefix_, namespacedef_='', name_='Header', pretty_print=pretty_print) the parameter outfile within the header export method takes the value of level.

The method signature of header export is export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='Header', pretty_print=True):

I have created classes in Python before and when I called class methods the self argument would be skipped and the first argument I pass into method call would be the next one after the self parameter. In this case though, the method call overwrites self with outfile and my Header object becomes a File object. This is bizarre and I don't understand why this would happen.

I have been running it on Anaconda with Python 3.6 in my Visual Studio Code debugger.

Here's the code I created.

import po3

def get_class( kls ):
    parts = kls.split('.')
    module = ".".join(parts[:-1])
    m = __import__( module )
    for comp in parts[1:]:
        m = getattr(m, comp)            
    return m

def recursiveInstantiation(obj):
    for key in vars(obj).keys():
        if '_' not in key and \
            'subclass' not in key and \
            'superclass' not in key and \
            'factory' not in key and \
            'export' not in key and \
            'build' not in key:
            subClass = recursiveInstantiation(get_class('po3.' + key))
            getattr(obj, 'set_' + key)(subClass)
    return obj

er = recursiveInstantiation(po3.EstablishRequest())

print(er.get_requestHeaderType()) # returns requestHeaderType object
print(er.get_requestHeaderType().get_Header()) # returns an exception posted below
#with open('file.xml', 'w') as outfile:
#    er.export(outfile, 0) # calling this produces the behavior I described above

Here's the output when I run this script:

<class 'po3.requestHeaderType'>
Traceback (most recent call last):
  File "c:\Users\arychlik\Desktop\New folder (3)\generateXml.py", line 26, in <module>
    print(er.get_requestHeaderType().get_Header())
TypeError: get_Header() missing 1 required positional argument: 'self'

I expect the method call to skip over the self parameter but it's actually assigning a value to self, it's overwriting it with a File object.

CodeMonkey
  • 22,825
  • 4
  • 35
  • 75
simnit
  • 1
  • 1
  • a) could you provide full trace stack? b) put an argument print(er.get_requestHeaderType().get_Header()), you should not, just to see what happens – Serge May 07 '19 at 14:46
  • a) the output I posted below is all I get. Let me know if there's a way to get more out of that stack trace b) I don't understand what you mean in part b). what argument do you want me to put in and into which method? – simnit May 07 '19 at 14:52
  • in 'I expect the method call to skip over the self parameter but it's actually assigning a value to self, it's overwriting it with a File object.' Which method is overwriting what? I do not think that in Python you can delete object (GC does it for you). And what is po3 – Serge May 07 '19 at 15:19
  • po3 is a collection of classes generated using generateDS python library from an XSD file. It's 40k lines long so I didn't post it here. Within that module I have class requestHeaderType which has export. Export calls export_children. export_children runs Header.export() with similar arguments it was called with. It's at that point when Header.export gets called, the self parameter is overwritten with the input to the function. – simnit May 07 '19 at 16:14
  • so when I run method with the following signature ```def export(self, outfile, level, namespaceprefix_='', namespacedef_='', name_='EstablishRequest', pretty_print=True):``` it executes ```self.exportChildren(outfile, level + 1, '', namespacedef_, name_='EstablishRequest', pretty_print=pretty_print)``` Then when I debug into exportChildren I see that ```self``` takes the value of outfile and outfile takes the value of level – simnit May 07 '19 at 16:19
  • there could be a bunch of different class instance and methods inside `export` and even `exportChildren` methods, all with a self param – Serge May 07 '19 at 17:35

0 Answers0