╭──────────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────────╮
│ plextraktsync/cli.py:28 in wrap │
│ │
│ 25 │ │ │ cmd = getattr(module, name) │
│ 26 │ │ │ │
│ 27 │ │ │ try: │
│ ❱ 28 │ │ │ │ cmd(*args, **kwargs) │
│ 29 │ │ │ except EOFError as e: │
│ 30 │ │ │ │ raise ClickException(f"Program requested terminal, No terminal is │
│ connected: {e}") │
│ 31 │ │ │ except ClickException as e: │
│ │
│ plextraktsync/commands/sync.py:74 in sync │
│ │
│ 71 │ │ │ w.print_plan(print=logger.info) │
│ 72 │ │ if dry_run: │
│ 73 │ │ │ logger.info("Enabled dry-run mode: not making actual changes") │
│ ❱ 74 │ │ run_async(runner, walker=w, dry_run=config.dry_run) │
│ 75 │
│ │
│ lib/python3.9/site-packages/decorator.py:232 in fun │
│ │
│ 229 │ │ def fun(*args, **kw): │
│ 230 │ │ │ if not kwsyntax: │
│ 231 │ │ │ │ args, kw = fix(args, kw, sig) │
│ ❱ 232 │ │ │ return caller(func, *(extras + args), **kw) │
│ 233 │ fun.__name__ = func.__name__ │
│ 234 │ fun.__doc__ = func.__doc__ │
│ 235 │ fun.__wrapped__ = func │
│ │
│ plextraktsync/decorators/coro.py:15 in coro │
│ │
│ 12 │ │
│ 13 │ https://github.com/pallets/click/issues/85#issuecomment-503464628 │
│ 14 │ """ │
│ ❱ 15 │ return asyncio.run(f(*args, **kwargs)) │
│ 16 │
│ │
│ /usr/local/Cellar/python@3.9/3.9.19/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py:44 in run │
│ │
│ 41 │ │ events.set_event_loop(loop) │
│ 42 │ │ if debug is not None: │
│ 43 │ │ │ loop.set_debug(debug) │
│ ❱ 44 │ │ return loop.run_until_complete(main) │
│ 45 │ finally: │
│ 46 │ │ try: │
│ 47 │ │ │ _cancel_all_tasks(loop) │
│ │
│ /usr/local/Cellar/python@3.9/3.9.19/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py:647 in │
│ run_until_complete │
│ │
│ 644 │ │ if not future.done(): │
│ 645 │ │ │ raise RuntimeError('Event loop stopped before Future completed.') │
│ 646 │ │ │
│ ❱ 647 │ │ return future.result() │
│ 648 │ │
│ 649 │ def stop(self): │
│ 650 │ │ """Stop running the event loop. │
│ │
│ plextraktsync/commands/sync.py:13 in run_async │
│ │
│ 10 │
│ 11 @coro │
│ 12 async def run_async(runner, **kwargs): │
│ ❱ 13 │ await runner.sync(**kwargs) │
│ 14 │
│ 15 │
│ 16 def sync( │
│ │
│ plextraktsync/sync/Sync.py:45 in sync │
│ │
│ 42 │ │ self.walker = walker │
│ 43 │ │ is_partial = walker.is_partial │
│ 44 │ │ │
│ ❱ 45 │ │ pm = self.pm │
│ 46 │ │ pm.hook.init(sync=self, pm=pm, is_partial=is_partial, dry_run=dry_run) │
│ 47 │ │ │
│ 48 │ │ if self.config.need_library_walk: │
│ │
│ /usr/local/Cellar/python@3.9/3.9.19/Frameworks/Python.framework/Versions/3.9/lib/python3.9/functools.py:993 in __get__ │
│ │
│ 990 │ │ │ │ # check if another thread filled cache while we awaited lock │
│ 991 │ │ │ │ val = cache.get(self.attrname, _NOT_FOUND) │
│ 992 │ │ │ │ if val is _NOT_FOUND: │
│ ❱ 993 │ │ │ │ │ val = self.func(instance) │
│ 994 │ │ │ │ │ try: │
│ 995 │ │ │ │ │ │ cache[self.attrname] = val │
│ 996 │ │ │ │ │ except TypeError: │
│ │
│ plextraktsync/sync/Sync.py:37 in pm │
│ │
│ 34 │ │ from .plugin import SyncPluginManager │
│ 35 │ │ │
│ 36 │ │ pm = SyncPluginManager() │
│ ❱ 37 │ │ pm.register_plugins(self) │
│ 38 │ │ │
│ 39 │ │ return pm │
│ 40 │
│ │
│ plextraktsync/sync/plugin/SyncPluginManager.py:68 in register_plugins │
│ │
│ 65 │ │ │ with measure_time(f"Created '{plugin.__name__}' plugin", │
│ logger=self.logger.debug): │
│ 66 │ │ │ │ p = plugin.factory(sync) │
│ 67 │ │ │ with measure_time(f"Registered '{plugin.__name__}' plugin", │
│ logger=self.logger.debug): │
│ ❱ 68 │ │ │ │ self.pm.register(p) │
│ 69 │
│ │
│ lib/python3.9/site-packages/apluggy/wrap/main.py:126 in register │
│ │
│ 123 │ ) -> Union[str, None]: │
│ 124 │ │ if callable(plugin): │
│ 125 │ │ │ plugin = plugin() │
│ ❱ 126 │ │ return super().register(plugin, name=name) │
│ 127 │ │
│ 128 │ def get_canonical_name(self, plugin: _Plugin) -> str: │
│ 129 │ │ '''Override to include class names in plugin names.''' │
│ │
│ lib/python3.9/site-packages/pluggy/_manager.py:157 in register │
│ │
│ 154 │ │ │
│ 155 │ │ # register matching hook implementations of the plugin │
│ 156 │ │ for name in dir(plugin): │
│ ❱ 157 │ │ │ hookimpl_opts = self.parse_hookimpl_opts(plugin, name) │
│ 158 │ │ │ if hookimpl_opts is not None: │
│ 159 │ │ │ │ normalize_hookimpl_opts(hookimpl_opts) │
│ 160 │ │ │ │ method: _HookImplFunction[object] = getattr(plugin, name) │
│ │
│ lib/python3.9/site-packages/pluggy/_manager.py:184 in parse_hookimpl_opts │
│ │
│ 181 │ │ customize how hook implementation are picked up. By default, returns the │
│ 182 │ │ options for items decorated with :class:`HookimplMarker`. │
│ 183 │ │ """ │
│ ❱ 184 │ │ method: object = getattr(plugin, name) │
│ 185 │ │ if not inspect.isroutine(method): │
│ 186 │ │ │ return None │
│ 187 │ │ try: │
│ │
│ /usr/local/Cellar/python@3.9/3.9.19/Frameworks/Python.framework/Versions/3.9/lib/python3.9/functools.py:993 in __get__ │
│ │
│ 990 │ │ │ │ # check if another thread filled cache while we awaited lock │
│ 991 │ │ │ │ val = cache.get(self.attrname, _NOT_FOUND) │
│ 992 │ │ │ │ if val is _NOT_FOUND: │
│ ❱ 993 │ │ │ │ │ val = self.func(instance) │
│ 994 │ │ │ │ │ try: │
│ 995 │ │ │ │ │ │ cache[self.attrname] = val │
│ 996 │ │ │ │ │ except TypeError: │
│ │
│ plextraktsync/sync/WatchListPlugin.py:60 in plex_wl │
│ │
│ 57 │ def plex_wl(self): │
│ 58 │ │ from plextraktsync.plex.PlexWatchList import PlexWatchList │
│ 59 │ │ │
│ ❱ 60 │ │ return PlexWatchList(self.plex.watchlist()) │
│ 61 │ │
│ 62 │ @cached_property │
│ 63 │ def sync_wl(self): │
│ │
│ plextraktsync/plex/PlexApi.py:249 in watchlist │
│ │
│ 246 │ │ │ "includeUserState": 0, │
│ 247 │ │ } │
│ 248 │ │ try: │
│ ❱ 249 │ │ │ return self.account.watchlist(libtype=libtype, **params) │
│ 250 │ │ except BadRequest as e: │
│ 251 │ │ │ self.logger.error(f"Error during {self.account.username} watchlist access: │
│ {e}") │
│ 252 │ │ │ return None │
│ │
│ lib/python3.9/site-packages/plexapi/myplex.py:947 in watchlist │
│ │
│ 944 │ │ params.update(kwargs) │
│ 945 │ │ │
│ 946 │ │ key = │
│ f'{self.METADATA}/library/sections/watchlist/{filter}{utils.joinArgs(params)}' │
│ ❱ 947 │ │ return self._toOnlineMetadata(self.fetchItems(key, maxresults=maxresults), │
│ **kwargs) │
│ 948 │ │
│ 949 │ def onWatchlist(self, item): │
│ 950 │ │ """ Returns True if the item is on the user's watchlist. │
│ │
│ lib/python3.9/site-packages/plexapi/base.py:281 in fetchItems │
│ │
│ 278 │ │ │ headers['X-Plex-Container-Start'] = str(container_start) │
│ 279 │ │ │ headers['X-Plex-Container-Size'] = str(container_size) │
│ 280 │ │ │ │
│ ❱ 281 │ │ │ data = self._server.query(ekey, headers=headers, params=params) │
│ 282 │ │ │ subresults = self.findItems(data, cls, ekey, **kwargs) │
│ 283 │ │ │ total_size = utils.cast(int, data.attrib.get('totalSize') or │
│ data.attrib.get('size')) or len(subresults) │
│ 284 │
│ │
│ lib/python3.9/site-packages/plexapi/myplex.py:234 in query │
│ │
│ 231 │ │ timeout = timeout or self._timeout │
│ 232 │ │ log.debug('%s %s %s', method.__name__.upper(), url, kwargs.get('json', '')) │
│ 233 │ │ headers = self._headers(**headers or {}) │
│ ❱ 234 │ │ response = method(url, headers=headers, timeout=timeout, **kwargs) │
│ 235 │ │ if response.status_code not in (200, 201, 204): # pragma: no cover │
│ 236 │ │ │ codename = codes.get(response.status_code)[0] │
│ 237 │ │ │ errtext = response.text.replace('\n', ' ') │
│ │
│ lib/python3.9/site-packages/requests_cache/session.py:127 in get │
│ │
│ 124 │ # Wrapper methods to add return type hints │
│ 125 │ def get(self, url: str, params=None, **kwargs) -> AnyResponse: # type: ignore │
│ 126 │ │ kwargs.setdefault('allow_redirects', True) │
│ ❱ 127 │ │ return self.request('GET', url, params=params, **kwargs) │
│ 128 │ │
│ 129 │ def options(self, url: str, **kwargs) -> AnyResponse: # type: ignore │
│ 130 │ │ kwargs.setdefault('allow_redirects', True) │
│ │
│ lib/python3.9/site-packages/requests_cache/session.py:183 in request │
│ │
│ 180 │ │ """ │
│ 181 │ │ headers = set_request_headers(headers, expire_after, only_if_cached, refresh, │
│ force_refresh) │
│ 182 │ │ with patch_form_boundary() if kwargs.get('files') else nullcontext(): │
│ ❱ 183 │ │ │ return super().request(method, url, *args, headers=headers, **kwargs) # │
│ type: ignore │
│ 184 │ │
│ 185 │ def send( │
│ 186 │ │ self, │
│ │
│ lib/python3.9/site-packages/niquests/sessions.py:552 in request │
│ │
│ 549 │ │ │ "allow_redirects": allow_redirects, │
│ 550 │ │ } │
│ 551 │ │ send_kwargs.update(settings) │
│ ❱ 552 │ │ resp = self.send(prep, **send_kwargs) │
│ 553 │ │ │
│ 554 │ │ return resp │
│ 555 │
│ │
│ lib/python3.9/site-packages/requests_cache/session.py:230 in send │
│ │
│ 227 │ │ elif actions.resend_request: │
│ 228 │ │ │ response = self._resend(request, actions, cached_response, **kwargs) # │
│ type: ignore │
│ 229 │ │ elif actions.send_request: │
│ ❱ 230 │ │ │ response = self._send_and_cache(request, actions, cached_response, **kwargs) │
│ 231 │ │ else: │
│ 232 │ │ │ response = cached_response # type: ignore # Guaranteed to be non-None by │
│ this point │
│ 233 │
│ │
│ lib/python3.9/site-packages/requests_cache/session.py:254 in │
│ _send_and_cache │
│ │
│ 251 │ │ If applicable, also handle conditional requests. │
│ 252 │ │ """ │
│ 253 │ │ request = actions.update_request(request) │
│ ❱ 254 │ │ response = super().send(request, **kwargs) │
│ 255 │ │ actions.update_from_response(response) │
│ 256 │ │ │
│ 257 │ │ if not actions.skip_write: │
│ │
│ lib/python3.9/site-packages/niquests/sessions.py:1208 in send │
│ │
│ 1205 │ │ │
│ 1206 │ │ try: │
│ 1207 │ │ │ # Send the request │
│ ❱ 1208 │ │ │ r = adapter.send(request, **kwargs) │
│ 1209 │ │ except TypeError: │
│ 1210 │ │ │ if "requests." in str(type(adapter)): │
│ 1211 │ │ │ │ # this is required because some people may do an incomplete migration. │
│ │
│ lib/python3.9/site-packages/niquests/adapters.py:931 in send │
│ │
│ 928 │ │ │ on_early_response(self.build_response(request, early_response)) │
│ 929 │ │ │
│ 930 │ │ try: │
│ ❱ 931 │ │ │ resp_or_promise = conn.urlopen( # type: ignore[call-overload,misc] │
│ 932 │ │ │ │ method=request.method, │
│ 933 │ │ │ │ url=url, │
│ 934 │ │ │ │ body=request.body, │
│ │
│ lib/python3.9/site-packages/urllib3/connectionpool.py:1471 in urlopen │
│ │
│ 1468 │ │ │ response_conn = conn if not release_conn else None │
│ 1469 │ │ │ │
│ 1470 │ │ │ # Make the request on the HTTPConnection object │
│ ❱ 1471 │ │ │ response = self._make_request( # type: ignore[call-overload,misc] │
│ 1472 │ │ │ │ conn, │
│ 1473 │ │ │ │ method, │
│ 1474 │ │ │ │ url, │
│ │
│ lib/python3.9/site-packages/urllib3/connectionpool.py:1036 in │
│ _make_request │
│ │
│ 1033 │ │ │ │ │ conn.conn_info.resolution_latency = timedelta() │
│ 1034 │ │ │ │ if conn.conn_info.request_sent_latency: │
│ 1035 │ │ │ │ │ conn.conn_info.request_sent_latency = None │
│ ❱ 1036 │ │ │ on_post_connection(conn.conn_info) │
│ 1037 │ │ │
│ 1038 │ │ if conn.is_multiplexed is False and multiplexed is True: │
│ 1039 │ │ │ # overruling │
│ │
│ lib/python3.9/site-packages/niquests/sessions.py:1114 in │
│ on_post_connection │
│ │
│ 1111 │ │ │ │ except ImportError: │
│ 1112 │ │ │ │ │ pass │
│ 1113 │ │ │ │ else: │
│ ❱ 1114 │ │ │ │ │ ocsp_verify( │
│ 1115 │ │ │ │ │ │ ptr_request, │
│ 1116 │ │ │ │ │ │ strict_ocsp_enabled, │
│ 1117 │ │ │ │ │ │ 0.2 if not strict_ocsp_enabled else 1.0, │
│ │
│ lib/python3.9/site-packages/niquests/extensions/_ocsp.py:405 in verify │
│ │
│ 402 │ │ │ │ │ │ raise ValueError │
│ 403 │ │ │ │ │ │
│ 404 │ │ │ │ │ if not proxies: │
│ ❱ 405 │ │ │ │ │ │ issuer_certificate = _ask_nicely_for_issuer( │
│ 406 │ │ │ │ │ │ │ url_parsed.hostname, │
│ 407 │ │ │ │ │ │ │ conn_info.destination_address, │
│ 408 │ │ │ │ │ │ │ timeout, │
│ │
│ lib/python3.9/site-packages/niquests/extensions/_ocsp.py:106 in │
│ _ask_nicely_for_issuer │
│ │
│ 103 │ │
│ 104 │ send_tls(sock, HANDSHAKE, client_hello) │
│ 105 │ │
│ ❱ 106 │ rec_type, server_hello = recv_tls(sock) │
│ 107 │ │
│ 108 │ if not rec_type == HANDSHAKE: │
│ 109 │ │ sock.close() │
│ │
│ lib/python3.9/site-packages/niquests/extensions/_picotls.py:733 in │
│ recv_tls │
│ │
│ 730 │ rec_type = recv_num_bytes(s, 1) │
│ 731 │ tls_version = recv_num_bytes(s, 2) │
│ 732 │ │
│ ❱ 733 │ assert tls_version == LEGACY_TLS_VERSION │
│ 734 │ │
│ 735 │ rec_len = bytes_to_num(recv_num_bytes(s, 2)) │
│ 736 │ rec = recv_num_bytes(s, rec_len) │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
AssertionError
Doing migration to
niquests(currently at ed7fd3d6 commit)And getting this error
Full trace:
Details
Reproduction Steps
I haven't made a minimal reproducer yet, will do this tomorrow(ish), if needed.
System Information
Details
{ "charset_normalizer": { "version": "3.4.0" }, "http1": { "h11": "0.14.0" }, "http2": { "jh2": "5.0.3" }, "http3": { "enabled": true, "qh3": "1.2.1" }, "idna": { "version": "3.10" }, "implementation": { "name": "CPython", "version": "3.9.19" }, "niquests": { "version": "3.9.1" }, "ocsp": { "enabled": true }, "platform": { "release": "19.6.0", "system": "Darwin" }, "system_ssl": { "version": "30300010" }, "urllib3.future": { "cohabitation_version": null, "version": "2.10.906" }, "wassima": { "certifi_fallback": false, "enabled": true, "version": "1.1.4" } }