Skip to content

Build variable replacement dict on init - #4731

Merged
The-Compiler merged 2 commits into
qutebrowser:masterfrom
jgkamat:jay/runner-loop
May 13, 2019
Merged

The-Compiler merged 2 commits into
qutebrowser:masterfrom
jgkamat:jay/runner-loop

Conversation

@jgkamat

@jgkamat jgkamat commented Apr 22, 2019 •

Copy link
Copy Markdown
Member

Essentially a little more fancy version of http://www.github.com/qutebrowser/qutebrowser/pull/4536

Continuation of #4652 (comment)

Haven't run all tests on this yet, but it seemed to pass what I thought would break. I'll fix anything if it comes up though (still not 100% sure this is safe).


This change is Reviewable

@jgkamat jgkamat added component: performance Issues with performance/benchmarking. status: work in progress labels Apr 22, 2019
@jgkamat jgkamat self-assigned this Apr 22, 2019
Comment thread qutebrowser/commands/runners.py Outdated
# pylint: disable=unused-import
from qutebrowser.mainwindow import tabbedbrowser
# pylint: enable=unused-import
ReplacementFunction = typing.Callable[['tabbedbrowser.TabbedBrowser'], str]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ReplacementFunction = typing.Callable[['tabbedbrowser.TabbedBrowser'], str]
_ReplacementFunction = typing.Callable[['tabbedbrowser.TabbedBrowser'], str]

as it shouldn't be needed from outside of this module

Comment thread qutebrowser/commands/runners.py Outdated
'url': lambda: url().toString(
def _init_variable_replacements() -> typing.Dict[str, ReplacementFunction]:
"""Return a dict from variable replacements to fns processing them."""
url = _current_url

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could just rename the _current_url function to _url instead 😉

Comment thread qutebrowser/commands/runners.py Outdated
return replacements


VARIABLE_REPLACEMENTS = types.MappingProxyType(_init_variable_replacements())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the MappingProxyType?

@user202729 user202729 Apr 26, 2019 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likely to ensure that it is not accidentally changed in some other places.

However I think it would be better to mark its type as Mapping[...] for a "compile-time" check.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapping is just a more loose version of Dict (like Sequence or Iterable compared to List), I don't think there's currently a way to make mypy check immutability.

As for using types.MappingProxyType: I don't think this makes sense here. The name clearly conveys that it's constant, so if it'd be modified somewhere else, that'd stand out anyways. That kind of stuff IMHO makes sense where accidental mutations can happen easily (like with objects coming from the config), but I don't think that's the case here.

@user202729 user202729 Apr 26, 2019 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, MutableMapping is a more loose version of Dict. Mapping is immutable.

Also, that works in mypy.

@user202729 user202729 Apr 26, 2019 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also from typing_extensions import Final (see python/mypy#5522 oops, accidentally referenced that PR for usage), but that is another kind of immutability - that the variable cannot be reassigned. It's not the case here.

@user202729

Copy link
Copy Markdown
Contributor

Unfortunately, mypy doesn't type check dynamically typed functions. So using Mapping to enforce immutability at check time won't work.

@The-Compiler

Copy link
Copy Markdown
Member

No, MutableMapping is a more loose version of Dict. Mapping is immutable.

My bad, you're right!

Unfortunately, mypy doesn't type check dynamically typed functions. So using Mapping to enforce immutability at check time won't work.

Since we're annotating more and more code in qutebrowser, I'd still go ahead with using typing.Mapping plus manual code review - the chance that someone accidentally mutates this dict seems pretty low anyways.

@jgkamat
jgkamat force-pushed the jay/runner-loop branch from 511bed4 to ff480a1 Compare May 12, 2019 04:45
@The-Compiler
The-Compiler merged commit ff480a1 into qutebrowser:master May 13, 2019
@The-Compiler

Copy link
Copy Markdown
Member

Thanks!

@jgkamat
jgkamat deleted the jay/runner-loop branch May 23, 2019 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: performance Issues with performance/benchmarking.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants