hyperlink
hyperlink copied to clipboard
Contextualize scheme registration API
hyperlink.register_scheme
mutates global state. That's convenient but amounts to an import time side effect. If I do this in module a
:
from hyperlink import register_scheme
register_scheme("blah")
I have to do this in module b
:
from hyperlink import URL
import a
u = URL.from_text("blah://blah.com")
Scheme registration should be localized, returning a new URL
-like object that knows about the registered schemes. That would let a
look like this:
import hyperlink.URL as _URL
URL = _URL.schemes({"blah": "blah"})
So that b
could do this:
from a import URL
u = URL.from_text({"blah": "blah"})
A context manager might be useful, too:
with URL.schemes({"blah": "blah"}) as blah_url:
u = blah_url.from_text("blah://blah.com")
I'm generally down for this kind of contextualization, but I must say that I would not want it to happen this way. This kind of invokes a JavaScript-like, prototype-driven approach. The explicit context approach I prefer is typified in ashes, where there's a default context implicit.
This is especially true in this case, where register_scheme
(and the future context object) are very very rarely touched. They're mostly there as escape valves for working with older versions of the library in the far flung future when many more schemes have been registered, or in case I've got a bug in the data in the default registry and they can't upgrade immediately.
Anyways, in short, yes, but I definitely wouldn't want schemes
hanging out on the URL
type's API.
(renamed bc "localize" makes me think l10n ;) )
I'd be happy if we can avoid an import-time side effect. I'm always up for more dependency injection, and while a context object that encapsulates the scheme registry and that users can definitely avoids mutating global state, it presents its own design challenges:
-
register_scheme
adds schemes tohyperlink
, whereas ashes' contexts share nothing with default behavior, except perhaps through inheritance. Ahyperlink
context object would have to either chain itself to existing context objects or allow itself to be cloned and then mutated. That's no less like prototypes than returning aURL
factory that knows about new schemes, so if one is unidiomatic so is the other. - The various methods that create
hyperlink.URL
instances --URL.__init__
,URL.from_text
, andURL.replace
-- would have to take a new argument. They already take a lot of arguments. This isn't a huge deal and will be less of a deal if closing #24 leads toScheme
objects.