Skip to content
This repository was archived by the owner on Apr 29, 2023. It is now read-only.

Support of Python 3.8. #123

@AntonDeMeester

Description

@AntonDeMeester

When I'm running PyXB on Python 3.8, I get an error when using the date field. I get a type error that there are too many arguments in the date datatype.

I've narrow it down, to the XsdLiteral method in the date class. Here 12 hours is added to the date field. But, it creates a new datatypes.date instance again. And because the new value is a datetime field (with the added 12 hours), the __new__ method throws an error as it has too many input items (year, month, day, hour, minute, second, microsecond and TZ).

Line in particular (datatypes.py 761)

@classmethod
def XsdLiteral (cls, value):
    # Work around strftime year restriction
    fmt = cls._Lexical_fmt
    rtz = value.xsdRecoverableTzinfo()
    if rtz is not None:
        # If the date is timezoned, convert it to UTC
        value -= value.tzinfo.utcoffset(value)
        value = value.replace(tzinfo=cls._UTCTimeZone)
    # Use the midpoint of the one-day interval to get the correct
    # month/day.
    value += datetime.timedelta(minutes=cls.__MinutesPerHalfDay) <<<<<<<<<<
    if value.year < 1900:
        fmt = fmt.replace('%Y', '%04d' % (value.year,))
        value = value.replace(year=1900)
    if rtz is not None:
        fmt += rtz.tzname(value)
    return value.strftime(fmt)

I've kind of solved the problem by overwriting the PyXB date class to remove args if they are exactly like we expect (12, 0, 0 , 0, None) as below. But I think that PyXB should solve the problem in a more structural way.

class customdate(pyxb.binding.datatypes.date):
    def __new__(cls, *args, **kw):
        # Because of some python, XsdLiteral (pyxb.binding.datatypes line 761)
        # creates a new custom date object, but with inputs like a datetime
        # Then the __new__ of date errors out.
        # So we're going to see if the hour is 12, and minutes, seconds, microseconds and TZ is 0 or empty
        # If so, we remove it
        # Similar issue: https://github.com/AuthorizeNet/sdk-python/issues/145

        if len(args) == 8:
            if args[3] == 12 and all(not bool(x) for x in args[-4:]):
                args = args[:3]
        return super().__new__(cls, *args, **kw)

Stacktrace of the error

 commissionmodule/test_commission.py:758: in base_test_integration
     pain_xml = payment_uploader.upload_payments(payments, return_xml=True)
 commissionmodule/base.py:394: in upload_payments
     payment_xml = self.payment_xml_generator.generate_payment_xml(payments)
 commissionmodule/base.py:379: in generate_payment_xml
     dom = doc.toDOM()
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:532: in toDOM
     self._toDOM_csc(bds, element)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:2694: in _toDOM_csc
     content.elementDeclaration.toDOM(dom_support, parent, content.value)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/content.py:1101: in toDOM
     value._toDOM_csc(dom_support, element)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:2694: in _toDOM_csc
     content.elementDeclaration.toDOM(dom_support, parent, content.value)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/content.py:1101: in toDOM
     value._toDOM_csc(dom_support, element)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:2694: in _toDOM_csc
     content.elementDeclaration.toDOM(dom_support, parent, content.value)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/content.py:1101: in toDOM
     value._toDOM_csc(dom_support, element)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:1137: in _toDOM_csc
     dom_support.appendTextChild(self, parent)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/utils/domutils.py:584: in appendTextChild
     return parent.appendChild(self.document().createTextNode(self.valueAsText(text)))
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/utils/domutils.py:402: in valueAsText
     return value.xsdLiteral()
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/basis.py:1010: in xsdLiteral
     return self.XsdLiteral(self)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/datatypes.py:761: in XsdLiteral
     value += datetime.timedelta(minutes=cls.__MinutesPerHalfDay)
 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
 cls = <class 'commissionmodule.pain_binding.ISODate'>
 args = (2020, 3, 13, 12, 0, 0, ...), kw = {'_from_xml': False}
 ctor_kw = {'day': 13, 'hour': 0, 'minute': 0, 'month': 3, ...}, value = 2020
 fi = 4, fn = 'day'
     def __new__ (cls, *args, **kw):
         args = cls._ConvertArguments(args, kw)
         ctor_kw = { }
         ctor_kw['year'] = cls._DefaultYear
         ctor_kw['month'] = cls._DefaultMonth
         ctor_kw['day'] = cls._DefaultDay
         ctor_kw['hour'] = 0
         ctor_kw['minute'] = 0
         ctor_kw['second'] = 0
         if kw.get('_nil'):
             pass
         elif 1 <= len(args):
             value = args[0]
             if isinstance(value, six.string_types):
                 if 1 != len(args):
                     raise TypeError('construction from string requires exactly 1 argument')
                 ctor_kw.update(cls._LexicalToKeywords(value))
             elif isinstance(value, (datetime.date, datetime.datetime)):
                 if 1 != len(args):
                     raise TypeError('construction from instance requires exactly 1 argument')
                 cls._SetKeysFromPython(value, ctor_kw, cls._ValidFields)
                 try:
                     tzinfo = value.tzinfo
                     if tzinfo is not None:
                         ctor_kw['tzinfo'] = tzinfo
                 except AttributeError:
                     pass
             else:
                 fi = 0
                 while fi < len(cls._ValidFields):
                     fn = cls._ValidFields[fi]
                     if fi < len(args):
                         ctor_kw[fn] = args[fi]
                     elif fn in kw:
                         ctor_kw[fn] = kw[fn]
                     kw.pop(fn, None)
                     fi += 1
                 if fi < len(args):
                     ctor_kw['tzinfo'] = args[fi]
                     fi += 1
                 if fi != len(args):
 >                   raise TypeError('function takes %d arguments plus optional tzinfo (%d given)' % (len(cls._ValidFields), len(args)))
 E                   TypeError: function takes 3 arguments plus optional tzinfo (8 given)
 /root/.local/share/virtualenvs/oper-product-ScP5jbQn/lib/python3.8/site-packages/pyxb/binding/datatypes.py:685: TypeError

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions