hyperlink icon indicating copy to clipboard operation
hyperlink copied to clipboard

Contextualize scheme registration API

Open markrwilliams opened this issue 7 years ago • 3 comments

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")

markrwilliams avatar Jul 03 '17 07:07 markrwilliams

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.

mahmoud avatar Jul 03 '17 07:07 mahmoud

(renamed bc "localize" makes me think l10n ;) )

mahmoud avatar Jul 03 '17 08:07 mahmoud

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:

  1. register_scheme adds schemes to hyperlink, whereas ashes' contexts share nothing with default behavior, except perhaps through inheritance. A hyperlink 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 a URL factory that knows about new schemes, so if one is unidiomatic so is the other.
  2. The various methods that create hyperlink.URL instances -- URL.__init__, URL.from_text, and URL.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 to Scheme objects.

markrwilliams avatar Jul 03 '17 18:07 markrwilliams