{"record":{"id":"61ea7a6dc715a3c9","repo":"arduino/Arduino","slug":"classes-extending-requestmethods-must-implement-th","errorCode":null,"errorMessage":"Classes extending RequestMethods must implement their own ``urlopen`` method.","messagePattern":"Classes extending RequestMethods must implement their own ``urlopen`` method\\.","errorType":"exception","errorClass":"NotImplemented","httpStatus":null,"severity":"error","filePath":"arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/request.py","lineNumber":56,"sourceCode":"    the request.\n\n    Initializer parameters:\n\n    :param headers:\n        Headers to include with all requests, unless other headers are given\n        explicitly.\n    \"\"\"\n\n    _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS'])\n    _encode_body_methods = set(['PATCH', 'POST', 'PUT', 'TRACE'])\n\n    def __init__(self, headers=None):\n        self.headers = headers or {}\n\n    def urlopen(self, method, url, body=None, headers=None,\n                encode_multipart=True, multipart_boundary=None,\n                **kw): # Abstract\n        raise NotImplemented(\"Classes extending RequestMethods must implement \"\n                             \"their own ``urlopen`` method.\")\n\n    def request(self, method, url, fields=None, headers=None, **urlopen_kw):\n        \"\"\"\n        Make a request using :meth:`urlopen` with the appropriate encoding of\n        ``fields`` based on the ``method`` used.\n\n        This is a convenience method that requires the least amount of manual\n        effort. It can be used in most situations, while still having the option\n        to drop down to more specific methods when necessary, such as\n        :meth:`request_encode_url`, :meth:`request_encode_body`,\n        or even the lowest level :meth:`urlopen`.\n        \"\"\"\n        method = method.upper()\n\n        if method in self._encode_url_methods:\n            return self.request_encode_url(method, url, fields=fields,\n                                            headers=headers,","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/arduino/Arduino/blob/a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee/arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/request.py#L38-L74","documentation":"RequestMethods.urlopen is an abstract method: the base class defines the request/request_encode_url/request_encode_body helpers but requires subclasses (like PoolManager or HTTPConnectionPool) to implement urlopen. Calling urlopen (directly or via request()) on a subclass that did not implement it raises this NotImplemented error.","triggerScenarios":"Subclassing urllib3.request.RequestMethods and forgetting to override urlopen, then calling instance.request('GET', url) or instance.urlopen('GET', url); calling urlopen on a bare RequestMethods() instance.","commonSituations":"Custom pool/pool-manager implementations for testing or mocking that only implement part of the interface; code refactored to extend RequestMethods directly; calling request() on an abstract base instantiated by mistake.","solutions":["Use a concrete class instead: urllib3.PoolManager() or HTTPConnectionPool(host).","If you subclass RequestMethods, implement urlopen(self, method, url, ...) with your send logic.","Check that your mock/stub in tests implements urlopen (or subclasses PoolManager and overrides it)."],"exampleFix":"// before\nclass MyClient(urllib3.request.RequestMethods):\n    pass\nMyClient().request('GET', 'https://example.com')  # NotImplemented\n// after\nclass MyClient(urllib3.request.RequestMethods):\n    def urlopen(self, method, url, body=None, headers=None, **kw):\n        return self._pool.urlopen(method, url, body=body, headers=headers, **kw)","handlingStrategy":"type-guard","validationCode":"if isinstance(client, urllib3.request.RequestMethods) and type(client).urlopen is urllib3.request.RequestMethods.urlopen:\n    raise TypeError('client must implement urlopen(); use PoolManager or override urlopen')","typeGuard":"import inspect, urllib3\ndef implements_urlopen(obj) -> bool:\n    fn = type(obj).urlopen\n    return not getattr(fn, '__isabstractmethod__', False) and inspect.getsourcefile(urllib3.request.RequestMethods.urlopen) != getattr(fn, '__code__', None) or fn is not urllib3.request.RequestMethods.urlopen","tryCatchPattern":"try:\n    resp = client.urlopen('GET', url)\nexcept NotImplementedError:\n    client = urllib3.PoolManager()\n    resp = client.urlopen('GET', url)","preventionTips":["Prefer composing a PoolManager instead of subclassing RequestMethods.","Keep abstract subclasses marked with abc.abstractmethod so instantiation fails early.","In mocks, subclass the real PoolManager rather than RequestMethods.","Add a unit test that calls request('GET', ...) on every client you ship."],"tags":["python","abstract-method","urllib3","api-misuse"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee","analyzedAt":"2026-09-06T10:13:38.901Z","contentChangedAt":"2026-09-06T10:13:38.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}