Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Fixed file objects with hyphen issue (ucfopen#647 ) and added test cases #650
base: develop
Are you sure you want to change the base?
Fixed file objects with hyphen issue (ucfopen#647 ) and added test cases #650
Changes from 4 commits
0383237
b087966
ae6c387
5c02d7e
51e59d1
66680c6
583e9c3
fd067da
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
While the problem here is with
content-type
, it technically happens with any value that contains a-
. I'm not aware of any other similar values in Canvas' responses, but in theory it's possible. Whatever solution we decide on forcontent-type
could be generalized by replacing all-
with_
.If there are major concerns with a broader approach, I'm happy to adopt a
content-only
fix for now and spin it off into its own issue for later.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.
On a cursory glance, I couldn't see any other response attributes that had hyphens. There are some other endpoints where camelCase is used (like the result and score endpoints), but those are only to report to IMS and LTI tools.
I think the question for me is which is more Pythonic - changing all the returned properties into class attributes or keeping the object as close to the returned structure (ie, keeping a hyphenated name and requiring the
getattr
method) from Canvas so the library matches the docs?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 was also thinking of making it more generic, like if the value contained a hyphen to set it as a value with an underscore. I think I'm fine for making this into a future issue.
It really might be easiest to change this class to store all of the variables in a dictionary. Then the
__getattribute__
and__getattr__
can be used to return from this dictionary by default. Then we can store both forms of the value with and without underscores. I'm fine with that as a separate issue but seems like it might be harder to get that fixed.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.
The original PR proposed the general replace-all-hyphens-with-underscores. I also favour that solution. Canvas might add new attributes that have hyphens instead of underscores.
I also think it makes the most sense to keep the hyphenated version and provide the underscored version for convenience, to match the documentation as mentioned above. But it's important to get it right so that they sync, in case they're changed (although it doesn't make sense to change this particular attribute).
Edit: Looked at @jonespm's solution below, I also think that's the way to do it.
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 appreciate what @bennettscience was suggesting here, but unfortunately the user doesn't typically have control over what gets passed into this function. Canvas is the one who sends the
content-type
attributes back, and we have to accept them as-is. Adding this will result in a bunch of warnings that the user will have no recourse to fix. We also wouldn't be able to remove the attribute in a future version until Canvas does.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.
Upon re-reading the discussion, was the intention to warn users who were trying to access
content-type
viagetattr
? In that case, a warning could make sense but it would have to be on the getter function, not the setter function as it is here.I think modifying
__getattribute__
could do the trick?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 @Thetwam I just looekd at this too and was thinking the same, that it's probably better to have this in a
__getattribute__
or possibly even better in__getattr__
rather than in theset_attributes
. Then you don't lose a similarly named attribute with.__getattr__
would only catch the ones that don't exist so wouldn't need to run through for everything.I think it's unlikely they'd have a content_type and content-type but it's possible for other headers.
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.
TIL there's difference between
__getattribute__
and__getattr__
.However, if I'm understanding it correctly, we'd still want to use
__getattribute__
for the time being, since the current behavior is to keepcontent-type
while addingcontent_type
.I moved the warning to
__getattribute__
, which passes thetest__getattribute__content_type_warns
test, whereas__getattr__
fails (doesn't throw the expected warning)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.
Nevermind, my idea wouldn't work as it is setting the values right on the class rather than as an dictionary in the class. This seems good to 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.
This test brings up some bigger questions about how we want to handle the case where both the
-
and_
versions of what is otherwise the same variable are set. In this case, the order of the items in the dictionary matters. I'll create and push new a test case the same as this one but reversing the order to demonstrate.It's pretty unlikely that Canvas would send back two attributes with only the
-
/_
differentiating them, let alone with different values, but it's something we'll need to consider how we want to handle.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 thought about this too, I think we can solve both of those problems but maybe in a separate issue. I don't think it's super likely either.
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.
Would it be worth adding tests that detect if Canvas would ever do this?
I do quite some API "reverse engineering" of APIs I want to use but don't have any official documentation (they're for "internal" use of the web UI). Then I add tests that will fail whenever some return value from the server changes.
Such tests must be added as a separate test suite run for this particular purpose. It would require a Canvas instance to run them against and, consequently, a login and token to the API. So not the ordinary test setup.
I'm leaning towards not worth it. Canvas is pretty stable and documents everything. So the likelihood of being useful is close to zero.