-
-
Notifications
You must be signed in to change notification settings - Fork 33
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
Handle missing default mod version, don't close db before rendering templates #378
Handle missing default mod version, don't close db before rendering templates #378
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hi @dumblob, do you mind if I ask what you meant by "(e.g. |
4d31a77
to
a904e42
Compare
Hi @HebaruSan - that's my mistake. I've done some quick testing back then and pytype seemed to handle those, but it actually didn't and falsly claimed they're "correct". So I'm sorry for the fuss - pytype doesn't support jinja templates 😢. |
Thanks for the response @dumblob! That makes sense and clears it up. Fingers crossed that some project somewhere creates this functionality someday! 🤞 |
Interesting, Jinja2 seems to do some magic to catch some of the |
Now this looks interesting:
By default JInja seems to catch AttributeErrors for objects passed to the template, and returns an object of type I think that is something worth activating. Maybe for production only, so we have a chance to catch potentially unwanted behavior during development. if not app.debug:
app.jinja_env.undefined = ChainableUndefined |
Nice find! Agreed that this looks helpful, done. |
Is |
Hm, it looks like it's installing the matching types- packages: |
Yeah, it's completely missing from the stubs package: https://github.com/python/typeshed/blob/master/stubs/Jinja2/jinja2/runtime.pyi#L85 The metadata says it's for Jinja 2.11, but that seems to be outright wrong: https://github.com/python/typeshed/blob/master/stubs/Jinja2/METADATA.toml |
38e373d
to
626d356
Compare
That stub solved it for mypy, but not pytype :(
That's a pretty important feature for a type checker... So that means, either ignore that error, or get rid of pytype again. Or fix the upstream typeshed stubs, but who knows how long it will take until they get released and arrive in all the tools. Edit: even worse, this feature exists, but only in a closed-source variant:
|
Yeah, Pytype isn't offering us any particular assistance here. I'll split that off to another branch in case we decide we want it later. |
cc32420
to
7b5e378
Compare
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.
🤞 especially interested in the effects of db session closing, let's see how it behaves.
Turns out the thing we fixed here I've broken again in #385
|
Without Added |
I started setting up to do this, but it appears that the typeshed stubs will be removed next month, so fixing them is unlikely to work out: python/typeshed#5423 However, that's not necessarily the end of the story for us. The reason they're being removed is that Flask 2 and Jinja2 3 have been released with type hints built-in, but we are currently pinned not to use them: SpaceDock/requirements-backend.txt Line 9 in 4dee33b
SpaceDock/requirements-backend.txt Line 16 in 4dee33b
So I wonder whether the rest of our typing for those modules will break once the removal happens. If so, the linked issue also notes that the versions we're using are "no longer supported", so upgrading may need to be a high priority. |
Problem
If a logged in admin user tries to open https://spacedock.info/mod/1967 , a 500 error occurs:
We found this in the server log:
Causes
default_version
, so the mod template throws an exception when it tries to access a property oflatest
with_session
wrapper closes the db session, which makescurrent_user
an invalid object (it is a rich sqlalchemy object which is stripped of its db connection at close)layout.html
which raisesDetachedInstanceError
becausecurrent_user
is invalidChanges
Mod.default_version
is not set, the backend code will default to using the one at the top of the list for the main compatibility fieldlatest
is null before using it, so the first exception won't be thrownwith_session
andhandle_generic_exception
no longer close the db; instead this is moved toteardown_request
, which is called after the request is handled, so the 500 error template can be rendered with a validcurrent_user
object instead of throwing an exceptionhttps://pythonise.com/series/learning-flask/python-before-after-request
Unsuccessful investigation
I was hoping that we could update our mypy configuration to catch this class of template errors; a
latest.game_version.friendly_version
reference in the backend Python code would have raised mypy errors becauselatest
is of typeOptional[Mod]
, which may beNone
.Sadly, this does not seem to be an option. I found just two pages even coming close to the idea of type checking for jinja2 templates:
https://www.eyrie.org/~eagle/journal/2019-11/001.html
A discussion of the problems that can slip through static type checking when jinja2 templates are involved:
Unfortunately the proposed solution is to create a "dataclass" for each template, with two downsides:
This seems like a non-solution to me.
https://jinja2schema.readthedocs.io/en/latest/
https://github.com/aromanovich/jinja2schema
Parses a jinja2 template and outputs a representation of the types of its inputs. But not in a format usable by mypy, and the project is idle for 4-7 years.
Unfortunately it appears that no one has gone all the way to integrating jinja2 with mypy, so we will have to continue handling these one case at a time.
We looked into adding a
pytype
test to the GitHub workflows, but it can't handleChainableUndefined
, so that is left out of this pull request.https://github.com/google/pytype