Open rominf opened 5 years ago
Right now I'm inclining to agree with your proposal but want to check it again for controversy.
I don't like usage of None
as not for None
value but the absence of value at all.
On the other hand, I don't see a better solution.
Would you prepare a PR for review?
@asvetlov it could be a special constant:
# in yarl:
QUERY_KEY_WITHOUT_VALUE = object()
# in code:
from yarl import QUERY_KEY_WITHOUT_VALUE
url = URL('https://api.crowdin.com/api/project/{project-identifier}/pre-translate')
url = url.with_query(key=project_key, json=QUERY_KEY_WITHOUT_VALUE)
It's more obvious, but IMHO more ugly.
I can prepare a PR tomorrow.
Agree, a constant is worse than just None
urllib.parse.parse_qsl()
does not distinguish empty value from absent value:
>>> parse_qsl('a=b&c=', keep_blank_values=True)
[('a', 'b'), ('c', '')]
>>> parse_qsl('a=b&c', keep_blank_values=True)
[('a', 'b'), ('c', '')]
As well as it does not distinguish the &
separator from the ;
separator.
>>> parse_qsl('a=b&c=d')
[('a', 'b'), ('c', 'd')]
>>> parse_qsl('a=b;c=d')
[('a', 'b'), ('c', 'd')]
If you want to create a query with non-standard representation (parameters without =
, with the ;
separator instead of &
, or %-encoded characters which do not need to be encoded in norm, or using encoding different from UTF-8), you need to change directly the query_string
or even the raw_query_string
attributes, but not the query
dict.
url = url.with_query(key=project_key)
url = url.with_query(url.query_string + '&json')
Sometimes query consists not only of pairs of keys and values but also can contain standalone keys. In my opinion, it's bad, but I encountered this a few times in different APIs. For example, I need to build a URL like: https://api.crowdin.com/api/project/{project_identifier}/pre-translate?key={project_key}&json (see https://support.crowdin.com/api/pre-translate/ for details).
I propose to make an interface look like this:
This is safe because now passing
None
as keyword argument value raisesTypeError
. If user wants to get an URL withjson=
(note that the last symbol is the equals sign), he passesjson=''
as he does now.