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

Support of Python 3.8. #123

Open
AntonDeMeester opened this issue Mar 16, 2020 · 7 comments
Open

Support of Python 3.8. #123

AntonDeMeester opened this issue Mar 16, 2020 · 7 comments

Comments

@AntonDeMeester
Copy link

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
@Safrone
Copy link

Safrone commented Jul 28, 2021

I faced a similar issue but it was when I tried to add a timedelta to a pyxb.binding.datatypes.date object. Worked around by calling .date() on the pyxb object tp get the datetime.date which worked in my instance

@efrainvalles
Copy link

still an issue today with PyXB 1.2.5. so the proposed by @AntonDeMeester fix here works great still.

@tvledesign
Copy link

I can confirm the fix from above works as well. If anyone runs into any issues with "binding" module not existing, I only made two edits which are the import and customdate class.

import pyxb.binding.datatypes as xs

class customdate(xs.date):

@Rohith-sreedharan
Copy link

can you share the code which is the fixing one, been struck to this past 2 days.

@Safrone
Copy link

Safrone commented Jan 4, 2023

this fork worked as a drop in replacement for me https://github.com/renalreg/PyXB-X
just pip install this and you don't need to change anything else

@Rohith-sreedharan
Copy link

Rohith-sreedharan commented Jan 6, 2023

I am sharing my code here, i ain't getting any response from authorize, i pip installed yours and its not charging any idea ???

Code: https://nekobin.com/qikiqumusu

@Rohith-sreedharan
Copy link

Ok i sorted it out, It wasn't on production, this works, thanks for the module. its a shame that these guys haven't worked into this since 2020.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants