2

I want to specify a timeout parameter for urllib.request.urlopen in python 3.

The docs say:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

What does [timeout, ]* mean?

I thought that all optional, named arguments (data=None, cafile=None ...) had to appear before all un-named arguments.

It looks here like timeout is an un-named argument. But it appears after data.

Looking just at that documentation, I have no idea whether to use:

  • urlopen(url, 123)
  • urlopen(url, timeout=123)
  • urlopen(url, [123])
  • urlopen(url, [123]*)

I can see from this post that the correct answer is urlopen(url, timeout=123). But if that's the case, why do the docs say [timeout, ]*, why not just timeout=None?

falsePockets
  • 3,826
  • 4
  • 18
  • 37

2 Answers2

1

This is a combination of independent features - square brackets and asterisk.

[timeout, ] means that timeout is optional argument - to simplify you may omit everything that is inside the brackets and the brackets - you will get urllib.request.urlopen(url, data=None, *, cafile=None, capath=None, cadefault=False, context=None).

* means that all the following arguments are keyword-only arguments - you must specify argument names.

  • Isn't everything *before* `*` (except `url`) also optional and keyword based? – falsePockets Sep 04 '19 at 23:10
  • also, why isn't there a comma between `]` and `*`? – falsePockets Sep 04 '19 at 23:12
  • @falsePockets `url` must be supplied, `data` and `timeout` are optional, all three may be suppliied without argument name, all arguments after `*` must be supplied with names. I guess there is no any difference between optional argument and argument with default value. The difference exists only in documentation because square brackets exist only in documentation. Comma is inside the brackets because it should be omitted together with optional argument - a bit confusing I believe but essentially just documentation syntax rule. –  Sep 05 '19 at 05:52
1

It is helpful to take a look at the actual source, which says:

def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
            *, cafile=None, capath=None, cadefault=False, context=None):
// actual implementation

which is actually way more clear compared to the documentation.

DocDriven
  • 3,726
  • 6
  • 24
  • 53
  • So `[timeout, ]*,` is actually identical to `timeout=socket._GLOBAL_DEFAULT_TIMEOUT`? Why didn't they just write that? What's the difference? – falsePockets Sep 04 '19 at 23:09
  • @ falsePockets: Actually, it is identical to ``timeout=socket._GLOBAL_DEFAULT_TIMEOUT, *``. As @Poolka already pointed out, this seems to be purely documentation syntax and is NOT valid Python code (try to define a function like in the docs, and the interpreter will mark it as invalid). So in short: the difference is that one is valid code and the other is not, and they probably thought that the documentation syntax might be easier to understand. This is obviously debatable. – DocDriven Sep 05 '19 at 07:43