effigies / BitTornado

UNMAINTAINED - John Hoffman's fork of the original bittorrent
Other
150 stars 44 forks source link

Support for the 'private' torrent flag in MetaInfo. #19

Closed samhocevar closed 8 years ago

samhocevar commented 8 years ago

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 what info can contain, as it will cause problems with extensions (and future extensions). For instance the root 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?

effigies commented 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?

effigies commented 8 years ago

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.

samhocevar commented 8 years ago

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.

effigies commented 8 years ago

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