Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

urllib.request.Request 'timeout' attribute needs to have a default #48329

Open
sidnei mannequin opened this issue Oct 8, 2008 · 12 comments
Open

urllib.request.Request 'timeout' attribute needs to have a default #48329

sidnei mannequin opened this issue Oct 8, 2008 · 12 comments
Labels
3.11 only security fixes easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@sidnei
Copy link
Mannequin

sidnei mannequin commented Oct 8, 2008

BPO 4079
Nosy @terryjreedy, @facundobatista, @ncoghlan, @orsenthil, @bitdancer
Files
  • issue-4079-1.patch
  • issue-4079-tests-1.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2008-10-08.18:29:58.218>
    labels = ['easy', 'type-bug', 'library', '3.11']
    title = "urllib.request.Request 'timeout' attribute needs to have a default"
    updated_at = <Date 2021-12-25.10:23:30.920>
    user = 'https://bugs.python.org/sidnei'

    bugs.python.org fields:

    activity = <Date 2021-12-25.10:23:30.920>
    actor = 'AlexWaygood'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2008-10-08.18:29:58.218>
    creator = 'sidnei'
    dependencies = []
    files = ['30873', '31003']
    hgrepos = []
    issue_num = 4079
    keywords = ['patch', 'easy']
    message_count = 12.0
    messages = ['74541', '75776', '76776', '103201', '103734', '192720', '192833', '193525', '193697', '193756', '193846', '409155']
    nosy_count = 8.0
    nosy_names = ['terry.reedy', 'facundobatista', 'jjlee', 'ncoghlan', 'orsenthil', 'sidnei', 'r.david.murray', 'italip']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue4079'
    versions = ['Python 3.11']

    @sidnei
    Copy link
    Mannequin Author

    sidnei mannequin commented Oct 8, 2008

    'urllib2' has introduced a configurable 'timeout' setting by assigning
    to the 'timeout' attribute of the urllib2.Request object. However the
    implementation is flawed:

    • the 'timeout' attribute is set in OpenerDirector.open() and nowhere else

    • if someone overrides OpenerDirector.open() (btw: mechanize does
      this), then the 'timeout' attribute will never be set, breaking
      other parts of the code which require the 'timeout' attribute to be
      present.

    A simple workaround for this would be to do one or more of:

    a) define the 'timeout' attribute as socket._GLOBAL_DEFAULT_TIMEOUT at
    class-level

    b) initialize the 'timeout' attribute on urllib2.Request.__init__()

    @sidnei sidnei mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Oct 8, 2008
    @orsenthil
    Copy link
    Member

    @jjlee
    Copy link
    Mannequin

    jjlee mannequin commented Dec 2, 2008

    This bug was known before the release -- unfortunately the original
    author of the patch didn't fix them in time. This and some other
    unresolved issues listed are listed on bpo-2451. "Somebody" should raise
    bugs about the rest of them too, and fix them.

    (Senthil, is that the bug you meant to refer to? You pasted this bug's
    own URL here, presumably you meant to paste the URL for a different bug?)

    @bitdancer
    Copy link
    Member

    Senthil, Facundo, is there a reason this bug shouldn't be fixed, or are we just waiting for someone to come up with a patch? I'm assuming the latter and setting it to languishing, but maybe this will wake somebody up who is interested in fixing it.

    @bitdancer bitdancer added easy stale Stale PR or inactive for long period of time. labels Apr 15, 2010
    @facundobatista
    Copy link
    Member

    I'm ok with the proposed changes from Sidnei (yes, a patch is needed).

    @italip
    Copy link
    Mannequin

    italip mannequin commented Jul 9, 2013

    patch initializes the 'timeout' attribute on urllib2.Request.__init__()

    @bitdancer bitdancer removed the stale Stale PR or inactive for long period of time. label Jul 9, 2013
    @bitdancer
    Copy link
    Member

    Now we need a test :)

    @italip
    Copy link
    Mannequin

    italip mannequin commented Jul 22, 2013

    patch adds regressions tests to ensure timeout value from OpenerDirector is honoured and a failing test for a default value for Request.timeout that passes when the patch that initialises Request.timeout is applied.

    @bitdancer
    Copy link
    Member

    Thanks, but the new test doesn't fail. With your test patch, test_default_values fails, but that is explicitly checking for the 'timeout' attribute, which isn't actually part of the public API. The new test passes even without the fix.

    Reading the original issue, it seems like the problem is a bit more subtle. To quote that issue:

    • API weirdness: Only some, special, urllib2.Request objects may be
      passed to handlers, because the constructor does not create objects with
      a .timeout.

    The original report here says the problem occurs if a subclass overrides 'open' (like Mechanize does). So that problem will only occur if a request gets passed to a handler without having passed through 'open'. But there is a question whether there is a way for the code that assumes the timeout attribute exists to fail that doesn't involve an override of 'open'. The answer may be no, but I haven't traced the logic or reviewed the API, so I don't know.

    However, it is clear that if open is overridden, and the code doing so doesn't care about timeouts and so doesn't do the attribute set itself, subsequent code will sometimes fail because it assumes that the attribute does exist. We could write a test that does that kind of override on 'open', and causes one of those code paths that assumes timeout exists to be called.

    But...I have some question, now, just how real an issue this is...if you override open, you really should be either calling it via super or replicating its functionality...so if there is not in fact any way to cause the lack of a timeout attribute to cause a failure without overriding open, there may not be a "real" issue here. Presumably mechanize ran into it because a keyword argument (new feature) was added. So the mechanize bug was really that there was a backward compatibility issue between 2.6 and previous versions. Is that still an issue for 2.7? Perhaps: there could still be code someone will forward port to 2.7 that overrides open and doesn't know about timeout. So it is worth fixing, since the fix is simple.

    @italip
    Copy link
    Mannequin

    italip mannequin commented Jul 26, 2013

    Ah sorry you are right the tests didn't test the specific case of someone overriding the OpenerDirector. The intent was to demonstrate that adding a default timeout to Request didn't break things.

    I think you are right about how much of an issue this is. I agree that if you are overriding open you probably should be replicating it's functionality and doing something sane about the timeout parameter.

    Reading the code and the online docs I think that the more pertinent issue here is that it isn't documented how the timeout is passed to the handlers. That is if someone implements a new handler that could timeout just from reading the documentation it isn't clear how the timeout is passed to the handler. Given that open adds the timeout to the Request object perhaps the issue should be that the timeout attribute should be added to the public api of the Request and the docs modified to suit, thus making it explicit how handlers get the expected timeout. That does uglify the api though as you would have two places where you could set the timeout (on the Request and via open) and currently calling open with a Request, with a non-default timeout, means that open would override the timeout on the Request with whatever was set on the call to open.

    So overall I'm fairly ambivalent about how much of an issue the original report was. I think the larger issue is that how timeouts are handled/passed to handlers/processors should probably be documented.

    @bitdancer
    Copy link
    Member

    Yes, this is a very good point. (And your passing test is worthwhile, you are correct.)

    People are expected to be able to write handlers, so clearly the timeout API needs to be documented, if for no other reason than to keep a handler writer from stomping on the timeout attribute inappropriately.

    But there is a code smell to this "API", and I wonder if it is worth someone taking time to think it all through again to see if there is a better way to do it :(

    @terryjreedy
    Copy link
    Member

    urllib2 became urllib.request in 3.x. In 2.6, 'timeout' became a parameter of both urlopen and OpenerDirector.open. In both cases the default was and is the 'global default timeout setting'. So 'timeout' has a default.

    Both functions take a Request object in lieu of a url. I see no indication that the Request object itself ever has a timeout attribute, at least not in .__init__. It certainly does not now. It seems that the idea was that timeouts are a property of an open action, not of the reusable Request object that wraps a url.

    CacheFTPHandler.setTimeout() is for FTP handlers.

    So it seems that this should be closed as either 'not a bug' or 'out of date'.

    @terryjreedy terryjreedy added the 3.11 only security fixes label Dec 24, 2021
    @terryjreedy terryjreedy changed the title new urllib2.Request 'timeout' attribute needs to have a default urllib.requst.Request 'timeout' attribute needs to have a default Dec 24, 2021
    @AlexWaygood AlexWaygood changed the title urllib.requst.Request 'timeout' attribute needs to have a default urllib.request.Request 'timeout' attribute needs to have a default Dec 25, 2021
    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 only security fixes easy stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants