Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 50 additions & 50 deletions ofxparse/ofxparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ def __init__(self, fh):

def read_headers(self):
head_data = self.fh.read(1024 * 10)
head_data = head_data[:head_data.find(six.b('<'))]
head_data = head_data[:head_data.find(b'<')]

for line in head_data.splitlines():
# Newline?
if line.strip() == six.b(""):
if line.strip() == b"":
break

header, value = line.split(six.b(":"))
header, value = line.split(b":")
header, value = header.strip().upper(), value.strip()

self.headers[header] = value
Expand Down Expand Up @@ -545,7 +545,7 @@ def parseInvstmtrs(cls, invstmtrs_list):
account.account_id = acctid_tag.contents[0].strip()
except IndexError:
account.warnings.append(
six.u("Empty acctid tag for %s") % invstmtrs_ofx)
u"Empty acctid tag for %s" % invstmtrs_ofx)
if cls.fail_fast:
raise

Expand All @@ -555,7 +555,7 @@ def parseInvstmtrs(cls, invstmtrs_list):
account.brokerid = brokerid_tag.contents[0].strip()
except IndexError:
account.warnings.append(
six.u("Empty brokerid tag for %s") % invstmtrs_ofx)
u"Empty brokerid tag for %s" % invstmtrs_ofx)
if cls.fail_fast:
raise

Expand Down Expand Up @@ -682,13 +682,13 @@ def parseInvestmentStatement(cls, invstmtrs_ofx):
statement.start_date = cls.parseOfxDateTime(
tag.contents[0].strip())
except IndexError:
statement.warnings.append(six.u('Empty start date.'))
statement.warnings.append(u'Empty start date.')
if cls.fail_fast:
raise
except ValueError:
e = sys.exc_info()[1]
statement.warnings.append(six.u('Invalid start date:\
%s') % e)
statement.warnings.append(u'Invalid start date:\
%s' % e)
if cls.fail_fast:
raise

Expand All @@ -698,11 +698,11 @@ def parseInvestmentStatement(cls, invstmtrs_ofx):
statement.end_date = cls.parseOfxDateTime(
tag.contents[0].strip())
except IndexError:
statement.warnings.append(six.u('Empty end date.'))
statement.warnings.append(u'Empty end date.')
except ValueError:
e = sys.exc_info()[1]
statement.warnings.append(six.u('Invalid end date: \
%s') % e)
statement.warnings.append(u'Invalid end date: \
%s' % e)
if cls.fail_fast:
raise

Expand All @@ -718,8 +718,8 @@ def parseInvestmentStatement(cls, invstmtrs_ofx):
if cls.fail_fast:
raise
statement.discarded_entries.append(
{six.u('error'): six.u("Error parsing positions: \
") + str(e), six.u('content'): investment_ofx}
{u'error': u"Error parsing positions: \
" + str(e), u'content': investment_ofx}
)

for transaction_type in InvestmentTransaction.AGGREGATE_TYPES:
Expand All @@ -732,8 +732,8 @@ def parseInvestmentStatement(cls, invstmtrs_ofx):
if cls.fail_fast:
raise
statement.discarded_entries.append(
{six.u('error'): transaction_type + ": " + str(e),
six.u('content'): investment_ofx}
{u'error': transaction_type + ": " + str(e),
u'content': investment_ofx}
)

for transaction_ofx in invstmtrs_ofx.findAll('invbanktran'):
Expand Down Expand Up @@ -862,8 +862,8 @@ def parseBalance(cls, statement, stmt_ofx, bal_tag_name, bal_attr,
setattr(statement, bal_attr, cls.toDecimal(balamt_tag))
except (IndexError, decimal.InvalidOperation):
statement.warnings.append(
six.u("%s balance amount was empty for \
%s") % (bal_type_string, stmt_ofx))
u"%s balance amount was empty for \
%s" % (bal_type_string, stmt_ofx))
if cls.fail_fast:
raise OfxParserException("Empty %s balance\
" % bal_type_string)
Expand All @@ -873,14 +873,14 @@ def parseBalance(cls, statement, stmt_ofx, bal_tag_name, bal_attr,
dtasof_tag.contents[0].strip()))
except IndexError:
statement.warnings.append(
six.u("%s balance date was empty for %s\
") % (bal_type_string, stmt_ofx))
u"%s balance date was empty for %s\
" % (bal_type_string, stmt_ofx))
if cls.fail_fast:
raise
except ValueError:
statement.warnings.append(
six.u("%s balance date was not allowed for \
%s") % (bal_type_string, stmt_ofx))
u"%s balance date was not allowed for \
%s" % (bal_type_string, stmt_ofx))
if cls.fail_fast:
raise

Expand All @@ -897,13 +897,13 @@ def parseStatement(cls, stmt_ofx):
dtstart_tag.contents[0].strip())
except IndexError:
statement.warnings.append(
six.u("Statement start date was empty for %s") % stmt_ofx)
u"Statement start date was empty for %s" % stmt_ofx)
if cls.fail_fast:
raise
except ValueError:
statement.warnings.append(
six.u("Statement start date was not allowed for \
%s") % stmt_ofx)
u"Statement start date was not allowed for \
%s" % stmt_ofx)
if cls.fail_fast:
raise

Expand All @@ -914,19 +914,19 @@ def parseStatement(cls, stmt_ofx):
dtend_tag.contents[0].strip())
except IndexError:
statement.warnings.append(
six.u("Statement start date was empty for %s") % stmt_ofx)
u"Statement start date was empty for %s" % stmt_ofx)
if cls.fail_fast:
raise
except ValueError:
msg = six.u("Statement start date was not formatted "
"correctly for %s")
msg = (u"Statement start date was not formatted "
u"correctly for %s")
statement.warnings.append(msg % stmt_ofx)
if cls.fail_fast:
raise
except TypeError:
statement.warnings.append(
six.u("Statement start date was not allowed for \
%s") % stmt_ofx)
u"Statement start date was not allowed for \
%s" % stmt_ofx)
if cls.fail_fast:
raise

Expand All @@ -936,7 +936,7 @@ def parseStatement(cls, stmt_ofx):
statement.currency = currency_tag.contents[0].strip().lower()
except IndexError:
statement.warnings.append(
six.u("Currency definition was empty for %s") % stmt_ofx)
u"Currency definition was empty for %s" % stmt_ofx)
if cls.fail_fast:
raise

Expand Down Expand Up @@ -971,20 +971,20 @@ def parseTransaction(cls, txn_ofx):
try:
transaction.type = type_tag.contents[0].lower().strip()
except IndexError:
raise OfxParserException(six.u("Empty transaction type"))
raise OfxParserException(u"Empty transaction type")
except TypeError:
raise OfxParserException(
six.u("No Transaction type (a required field)"))
u"No Transaction type (a required field)")

name_tag = txn_ofx.find('name')
if hasattr(name_tag, "contents"):
try:
transaction.payee = name_tag.contents[0].strip()
except IndexError:
raise OfxParserException(six.u("Empty transaction name"))
raise OfxParserException(u"Empty transaction name")
except TypeError:
raise OfxParserException(
six.u("No Transaction name (a required field)"))
u"No Transaction name (a required field)")

memo_tag = txn_ofx.find('memo')
if hasattr(memo_tag, "contents"):
Expand All @@ -1009,13 +1009,13 @@ def parseTransaction(cls, txn_ofx):
transaction.amount = 0
else:
raise OfxParserException(
six.u("Invalid Transaction Amount: '%s'") % amt_tag.contents[0])
u"Invalid Transaction Amount: '%s'" % amt_tag.contents[0])
except TypeError:
raise OfxParserException(
six.u("No Transaction Amount (a required field)"))
u"No Transaction Amount (a required field)")
else:
raise OfxParserException(
six.u("Missing Transaction Amount (a required field)"))
u"Missing Transaction Amount (a required field)")

date_tag = txn_ofx.find('dtposted')
if hasattr(date_tag, "contents"):
Expand All @@ -1029,10 +1029,10 @@ def parseTransaction(cls, txn_ofx):
raise OfxParserException(str(ve))
except TypeError:
raise OfxParserException(
six.u("No Transaction Date (a required field)"))
u"No Transaction Date (a required field)")
else:
raise OfxParserException(
six.u("Missing Transaction Date (a required field)"))
u"Missing Transaction Date (a required field)")

user_date_tag = txn_ofx.find('dtuser')
if hasattr(user_date_tag, "contents"):
Expand All @@ -1052,29 +1052,29 @@ def parseTransaction(cls, txn_ofx):
try:
transaction.id = id_tag.contents[0].strip()
except IndexError:
raise OfxParserException(six.u("Empty FIT id (a required \
field)"))
raise OfxParserException(u"Empty FIT id (a required \
field)")
except TypeError:
raise OfxParserException(six.u("No FIT id (a required field)"))
raise OfxParserException(u"No FIT id (a required field)")
else:
raise OfxParserException(six.u("Missing FIT id (a required \
field)"))
raise OfxParserException(u"Missing FIT id (a required \
field)")

sic_tag = txn_ofx.find('sic')
if hasattr(sic_tag, 'contents'):
try:
transaction.sic = sic_tag.contents[0].strip()
except IndexError:
raise OfxParserException(six.u("Empty transaction Standard \
Industry Code (SIC)"))
raise OfxParserException(u"Empty transaction Standard \
Industry Code (SIC)")

if transaction.sic is not None and transaction.sic in mcc.codes:
try:
transaction.mcc = mcc.codes.get(transaction.sic, '').get('combined \
description')
except IndexError:
raise OfxParserException(six.u("Empty transaction Merchant Category \
Code (MCC)"))
raise OfxParserException(u"Empty transaction Merchant Category \
Code (MCC)")
except AttributeError:
if cls.fail_fast:
raise
Expand All @@ -1084,8 +1084,8 @@ def parseTransaction(cls, txn_ofx):
try:
transaction.checknum = checknum_tag.contents[0].strip()
except IndexError:
raise OfxParserException(six.u("Empty Check (or other reference) \
number"))
raise OfxParserException(u"Empty Check (or other reference) \
number")

return transaction

Expand Down
20 changes: 10 additions & 10 deletions tests/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def testTextStartsWithTag(self):
self.assertEqual(ofx.account.number, '1234123412341234')

def testUTF8(self):
fh = six.BytesIO(six.b("""OFXHEADER:100
fh = six.BytesIO(b"""OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
Expand All @@ -74,7 +74,7 @@ def testUTF8(self):
OLDFILEUID:NONE
NEWFILEUID:NONE

"""))
""")
ofx_file = self.OfxFileCls(fh)
headers = ofx_file.headers
data = ofx_file.fh.read()
Expand All @@ -83,7 +83,7 @@ def testUTF8(self):
self.assertHeadersTypes(headers)

def testCP1252(self):
fh = six.BytesIO(six.b("""OFXHEADER:100
fh = six.BytesIO(b"""OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
Expand All @@ -92,7 +92,7 @@ def testCP1252(self):
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
"""))
""")
ofx_file = self.OfxFileCls(fh)
headers = ofx_file.headers
result = ofx_file.fh.read()
Expand All @@ -101,7 +101,7 @@ def testCP1252(self):
self.assertHeadersTypes(headers)

def testUTF8Japanese(self):
fh = six.BytesIO(six.b("""OFXHEADER:100
fh = six.BytesIO(b"""OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
Expand All @@ -110,7 +110,7 @@ def testUTF8Japanese(self):
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
"""))
""")
ofx_file = self.OfxFileCls(fh)
headers = ofx_file.headers
result = ofx_file.fh.read()
Expand All @@ -119,7 +119,7 @@ def testUTF8Japanese(self):
self.assertHeadersTypes(headers)

def testBrokenLineEndings(self):
fh = six.BytesIO(six.b("OFXHEADER:100\rDATA:OFXSGML\r"))
fh = six.BytesIO(b"OFXHEADER:100\rDATA:OFXSGML\r")
ofx_file = self.OfxFileCls(fh)
self.assertEqual(len(ofx_file.headers.keys()), 2)

Expand All @@ -128,7 +128,7 @@ class TestOfxPreprocessedFile(TestOfxFile):
OfxFileCls = OfxPreprocessedFile

def testPreprocess(self):
fh = six.BytesIO(six.b("""OFXHEADER:100
fh = six.BytesIO(b"""OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
Expand All @@ -139,7 +139,7 @@ def testPreprocess(self):
NEWFILEUID:NONE

<OFX><DTASOF><![CDATA[></tricky]]><LEAVE ALONE><VAL.UE>a<VAL_UE>b<TE_ST></TE_ST><TE.ST></TE.ST><INVBAL><BALLIST><BAL><NAME>Net<DTASOF>2222</BAL><BAL><NAME>Gross<DTASOF>3333</BAL></BALLIST></INVBAL></OFX>
"""))
""")
expect = """OFXHEADER:100
DATA:OFXSGML
VERSION:102
Expand All @@ -159,7 +159,7 @@ def testPreprocess(self):

class TestParse(TestCase):
def testEmptyFile(self):
fh = six.BytesIO(six.b(""))
fh = six.BytesIO(b"")
self.assertRaises(OfxParserException, OfxParser.parse, fh)

def testThatParseWorksWithoutErrors(self):
Expand Down
4 changes: 3 additions & 1 deletion utils/ofx2xlsx.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import print_function

from ofxparse import OfxParser
import pandas as pd

Expand Down Expand Up @@ -49,7 +51,7 @@
df['id'] = df['id'].str[:args.id_length] # clip the last part of the ID which changes from download to download
data[account.number] = df

print "Writing result to", args.output
print("Writing result to", args.output)
writer = pd.ExcelWriter(args.output)

for account_number, df in data.iteritems():
Expand Down