Closed samhocevar closed 8 years ago
Yeah, I thought a bit about the constrained dictionaries. They are definitely less flexible than Python data structures in general, and that's kind of the point. The reason I like them is that you can encode validity checks directly in, and not worry about "Did I run check_info
?" for example. (Though check_info
does still check some things that are harder to encode as constraints.) Because we need to be able to read and, especially, write files made by other programs, we need to be very confident of their contents.
That said, they definitely seem to be causing issues for you. I can try a couple things:
1) Make Info
subclass from a more flexible version of TypedDict
, where known fields are validated, and unknown fields are permitted as usual.
2) Try to go through all the BEPs and permit any new field that I find.
3) Revert the TypedDict
change for Info
(and MetaInfo
?).
What do you think makes the most sense?
Try the bep_27
branch. It works on your test code, but feel free to stress it more.
What caused the problem here is that there are dynamic keys in Info
, so they don't exist as key-value pairs in the underlying dictionary, which is why the valid_keys
dict was used as a base. The patch I added distinguishes between "required" (sort-of, since one of length
xor files
is required) base_keys
and possible valid_keys
.
Yes, having base_keys
/ valid_keys
seems like a good way to me to tackle the issue. I will test some more, to check whether subclassing Info
or MetaInfo
will allow me to add custom keys if ever necessary.
The simplest hack to permit new keys:
info = Info(...)
info.valid_keys = None
(Same for MetaInfo
, or any other TypedDict
.)
Subclassing:
class MyInfo(Info):
typemap = Info.typemap.copy()
typemap[newkey] = type
This simple patch allows to create private torrents as per BEP-0027.
As a side note, the additional safeties added to the
Info
class seem to have brought their share of issues, including this one. It doesn’t seem very pythonish to me to hardcode whatinfo
can contain, as it will cause problems with extensions (and future extensions). For instance theroot hash
field (BEP-0030) should be allowed, too.Also I could not find an elegant way to say that
private
is actually an optional field, so it is always serialised in the torrent. Does it suit you nonetheless?