-
Notifications
You must be signed in to change notification settings - Fork 73
Support of Python 3.8. #123
Description
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