-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Key Account.transactions
by account type instead of str
#49
Key Account.transactions
by account type instead of str
#49
Conversation
I'm not sure what my preference would be here. I think I'd actually lean towards making the What are your thoughts on this? The biggest downside is that it wouldn't be retro-compatible. |
I was thinking the exact same. I would also prefer making the I think changing it to |
I agree, though I would use a new hotfix version for the initial one, and a minor version later. Would you be willing to make the initial changes in this PR? |
@isaacharrisholt Sure, did that. What do you think of the latest commit? |
quiffen/core/account.py
Outdated
warnings.warn(f'You passed in a value of {header!r} for argument "header", ' | ||
f'but it should have been of type "AccountType". Starting with ' | ||
f'the next major release, this will become a type error.', | ||
DeprecationWarning) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of things: next *minor release
Secondly, could we format with a hanging indent? :)
warnings.warn(
f'You passed in a value of {header!r} for argument "header", '
f'but it should have been of type "AccountType". Starting with '
f'the next major release, this will become a type error.',
DeprecationWarning,
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, the second and third lines don't need to be f-strings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you looking to follow semver? According to semver, a breaking change requires a major release, which is why I wrote this here. :) Happy to change the copy here, though, if you don't mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and, changed it to a hanging indent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh really? I thought a breaking change could have a minor release, and it was just hotfixes that had to be version compatible? Maybe I need to do some reading...
Actually, thinking about this, I believe Pydantic will automatically convert the string to an enum if it's valid, will it not? |
quiffen/core/account.py
Outdated
header = AccountType(header.strip().split(':')[-1]) | ||
self._last_header = header | ||
self._last_header = self._convert_deprecated_str_header(header) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading this again, I'm perhaps a little confused. If we were always converting to an account type, could we not just change the type hint for the transactions
field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were not necessarily always converting since you can also call .set_header()
manually outside of this function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, but surely we could just do self.header = AccountType(header)
there? That should work fine, and throw and error if it's an invalid account type, which we want? I don't mind people being able to pass in strings (hence the strings everywhere in the docs and tests), as long as things end up the right types in the objects. Also, everything is pretty well type-hinted, so people's IDEs should scream at them if they try and use the wrong things in the wrong places.
At the end of the day, there's only so much defensive programming we can do. Python is inherently flexible, and you'll always be able to break things like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to change that, but that could potentially be a breaking change, if people used .set_header()
to set other strings that are not valid QIF account types. Shall I?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a breaking change if it fixes unintended behaviour 🤷🏻♂️
I think we should probably fix this, then run a static type checker like pyright
against the codebase. I'm also tempted to introduce black
for formatting. That's what I've done with iTmpl and it makes life so much easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, fine with me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just make sure to squash the commits on this PR before merging 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, will do :D
I briefly tested this and it doesn't seem to, as far as I can tell |
0889008
to
3b10266
Compare
Account.transactions
by account type instead of str
Account.transactions
by account type instead of strAccount.transactions
by account type instead of str
Squashed everything. How does that look? |
3b10266
to
705fb12
Compare
Tested this some more. You're right it in that it automatically converts str to enum during object instantiation in a case like this: It does not to do that at any later time, though, e.g. when re-setting any of the attributes. |
Yeah, I thought so. That's one of the benefits of Pydantic. |
tests/test_account.py
Outdated
@@ -125,6 +125,7 @@ def test_add_transaction_invalid_header(): | |||
account = Account(name='Test Account') | |||
transaction = Transaction(date=datetime(2022, 2, 1), amount=0) | |||
with pytest.raises(ValueError): | |||
# noinspection PyTypeChecker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these comments for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took them out :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I think they're perhaps specific to your editor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think they're IntelliJ-specific
51d6ef6
to
8ef6259
Compare
Do you have merge permissions? |
I don't think so! Thanks for merging! :) |
In
account.py
, thetransactions
field is defined as:But there were a few places where we were using an instance of the
AccountType
enum as the key instead of the string, which could result in invalid QIF files being produced that read things likeinstead of