[Python-ideas] Pre-PEP Adding A Secrets Module To The Standard Library

Nick Coghlan ncoghlan at gmail.com
Mon Sep 21 11:25:00 CEST 2015

On 21 September 2015 at 08:07, Andrew Barnert <abarnert at yahoo.com> wrote:
> If T is a word list--that is, an Iterable of str or bytes--you want to return a str or a bytes, not a T.
> Also, making it work that generically will make the code much more complicated, to the point where it no longer serves as useful sample code to rank novices. You have to extract the first element of T, then do your choosing off chain([first], T) instead of off T, then type(first).join; all of that is more complicated than the actual logic, and will obscure the important part we want novices to learn if they read the source.
> Also, I think for word lists, I think you'd want a way to specify actual passphrases vs. the xkcd 936 idea of using passphrases as passwords even for sites that don't accept spaces, like "correcthorsebatterystaple". Maybe via a sep=' ' parameter? That would be very confusing if it's ignored when T is string-like but used when T is a non-string-like iterable of string-likes.
> I think it's better to require T to be string-like than to try to generalize it, and maybe add a separate passphrase function that takes (words: Sequence[T], sep: T) -> T. (Although I'm not sure how to default to ' ' vs b' ' based on the type of T... But maybe this does need to handle bytes, so Sequence[str] is fine?)

Simpler is better here, so I'll revise the text based suggestions to:

    secrets.password(result_len: int,
alphabet=string.ascii_letters+string.digits+string.punctuation: str)
-> str
    secrets.passphrase(result_len: int, words: Sequence[str], sep=' ') -> str

>> * Lower level building blocks:
>>    secrets.choice(container)
>>    # Hold off on other SystemRandom methods?
>> (I don't have a strong opinion on that last point, as it's the higher
>> level APIs that I think are the important aspect of this proposal)
> I think randrange is definitely worth having. Even the OpenSSL and arc4random APIs provide something equivalent. If you're a novice, and following a blog post that says to use your language's equivalent of randbelow(1000000), are you going to think of choice(range(1000000))? And, if you do, are you going to convince yourself that this is reasonable and not going to create a slew of million-element lists?

Sure, that makes sense, while still keeping the secrets module focused
on integers.

getrandbits() is an interesting one, as it opens up the option of
"secrets.getrandbits(128).to_bytes()" as a pointlessly slower
alternative to "secrets.token(128 // 8)", while
"secrets.getrandbits(128)" itself would be directly equivalent to the
proposed "secrets.serial_number(128 // 8)"

So perhaps it makes sense to just drop the serial_number() idea and
have getrandbits() instead.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list