Sample

pyint-63c43928c958-SRC

Unmodified source class

Lines245

Scores

MethodScoreScale
Posnett00–1; higher is more readable
Dorn0.0780–1; higher is more readable
Mi0.5720–1; higher is more readable
LLOC160Logical lines; fewer is more readable
DeepSeek V4 Pro13.330–20; mean of three runs
GPT-6.1 Sol150–20; mean of three runs
BTTF0.320–1; higher is more readable

Views

Source code

from __future__ import annotations import hashlib import os import re import threading import time import warnings from base64 import b64encode from typing import TYPE_CHECKING, Any, Final, cast, overload from ._internal_utils import to_native_string from .compat import basestring, str, urlparse from .cookies import extract_cookies_to_jar from .utils import parse_dict_header class HTTPDigestAuth(AuthBase): """Attaches HTTP Digest Authentication to the given Request object.""" username: bytes | str password: bytes | str _thread_local: threading.local last_nonce: str nonce_count: int chal: dict[str, str] pos: int | None num_401_calls: int | None @overload def __init__(self, username: str, password: str) -> None: ... @overload def __init__(self, username: bytes, password: bytes) -> None: ... def __init__(self, username: bytes | str, password: bytes | str) -> None: self.username = username self.password = password # Keep state in per-thread local storage self._thread_local = threading.local() def init_per_thread_state(self) -> None: # Ensure state is initialized just once per-thread if not hasattr(self._thread_local, "init"): self._thread_local.init = True self._thread_local.last_nonce = "" self._thread_local.nonce_count = 0 self._thread_local.chal = {} self._thread_local.pos = None self._thread_local.num_401_calls = None def build_digest_header(self, method: str, url: str) -> str | None: """ :rtype: str """ realm = self._thread_local.chal["realm"] nonce = self._thread_local.chal["nonce"] qop = self._thread_local.chal.get("qop") algorithm = self._thread_local.chal.get("algorithm") opaque = self._thread_local.chal.get("opaque") hash_utf8 = None if algorithm is None: _algorithm = "MD5" else: _algorithm = algorithm.upper() # lambdas assume digest modules are imported at the top level if _algorithm == "MD5" or _algorithm == "MD5-SESS": def md5_utf8(x: str | bytes) -> str: if isinstance(x, str): x = x.encode("utf-8") return hashlib.md5(x, usedforsecurity=False).hexdigest() hash_utf8 = md5_utf8 elif _algorithm == "SHA": def sha_utf8(x: str | bytes) -> str: if isinstance(x, str): x = x.encode("utf-8") return hashlib.sha1(x, usedforsecurity=False).hexdigest() hash_utf8 = sha_utf8 elif _algorithm == "SHA-256": def sha256_utf8(x: str | bytes) -> str: if isinstance(x, str): x = x.encode("utf-8") return hashlib.sha256(x, usedforsecurity=False).hexdigest() hash_utf8 = sha256_utf8 elif _algorithm == "SHA-512": def sha512_utf8(x: str | bytes) -> str: if isinstance(x, str): x = x.encode("utf-8") return hashlib.sha512(x, usedforsecurity=False).hexdigest() hash_utf8 = sha512_utf8 if hash_utf8 is None: return None def KD(s: str, d: str) -> str: return hash_utf8(f"{s}:{d}") # XXX not implemented yet entdig = None p_parsed = urlparse(url) #: path is request-uri defined in RFC 2616 which should not be empty path = p_parsed.path or "/" if p_parsed.query: path += f"?{p_parsed.query}" A1 = f"{self.username}:{realm}:{self.password}" A2 = f"{method}:{path}" HA1 = hash_utf8(A1) HA2 = hash_utf8(A2) if nonce == self._thread_local.last_nonce: self._thread_local.nonce_count += 1 else: self._thread_local.nonce_count = 1 ncvalue = f"{self._thread_local.nonce_count:08x}" s = str(self._thread_local.nonce_count).encode("utf-8") s += nonce.encode("utf-8") s += time.ctime().encode("utf-8") s += os.urandom(8) cnonce = hashlib.sha1(s, usedforsecurity=False).hexdigest()[:16] if _algorithm == "MD5-SESS": HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}") # type: ignore[reportConstantRedefinition] # RFC 2617 terminology if not qop: respdig = KD(HA1, f"{nonce}:{HA2}") elif qop == "auth" or "auth" in qop.split(","): noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}" respdig = KD(HA1, noncebit) else: # XXX handle auth-int. return None self._thread_local.last_nonce = nonce # XXX should the partial digests be encoded too? base = ( f'username="{self.username}", realm="{realm}", nonce="{nonce}", ' f'uri="{path}", response="{respdig}"' ) if opaque: base += f', opaque="{opaque}"' if algorithm: base += f', algorithm="{algorithm}"' if entdig: base += f', digest="{entdig}"' if qop: base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"' return f"Digest {base}" def handle_redirect(self, r: Response, **kwargs: Any) -> None: """Reset num_401_calls counter on redirects.""" if r.is_redirect: self._thread_local.num_401_calls = 1 def handle_401(self, r: Response, **kwargs: Any) -> Response: """ Takes the given response and tries digest-auth, if needed. :rtype: requests.Response """ # If response is not 4xx, do not auth # See https://github.com/psf/requests/issues/3772 if not 400 <= r.status_code < 500: self._thread_local.num_401_calls = 1 return r if self._thread_local.pos is not None: # Rewind the file position indicator of the body to where # it was to resend the request. if (seek := getattr(r.request.body, "seek", None)) is not None: seek(self._thread_local.pos) s_auth = r.headers.get("www-authenticate", "") if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2: self._thread_local.num_401_calls += 1 pat = re.compile(r"digest ", flags=re.IGNORECASE) self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1)) # Consume content and release the original connection # to allow our new request to reuse the same one. r.content r.close() prep = r.request.copy() cookie_jar = cast("CookieJar", prep._cookies) extract_cookies_to_jar(cookie_jar, r.request, r.raw) prep.prepare_cookies(cookie_jar) _digest_auth = self.build_digest_header( cast(str, prep.method), cast(str, prep.url) ) if _digest_auth: prep.headers["Authorization"] = _digest_auth _r = r.connection.send(prep, **kwargs) _r.history.append(r) _r.request = prep return _r self._thread_local.num_401_calls = 1 return r def __call__(self, r: PreparedRequest) -> PreparedRequest: # Initialize per-thread state, if needed self.init_per_thread_state() # If we have a saved nonce, skip the 401 if self._thread_local.last_nonce: _digest_auth = self.build_digest_header( cast(str, r.method), cast(str, r.url) ) if _digest_auth: r.headers["Authorization"] = _digest_auth if (tell := getattr(r.body, "tell", None)) is not None: self._thread_local.pos = tell() else: # In the case of HTTPDigestAuth being reused and the body of # the previous request was a file-like object, pos has the # file position of the previous body. Ensure it's set to # None. self._thread_local.pos = None r.register_hook("response", self.handle_401) r.register_hook("response", self.handle_redirect) self._thread_local.num_401_calls = 1 return r def __eq__(self, other: object) -> bool: return all( [ self.username == getattr(other, "username", None), self.password == getattr(other, "password", None), ] ) def __ne__(self, other: Any) -> bool: return not self == other

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.9921.788−327.419
Source linesThe number of non-empty source lines.245+98
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.498−6.747

Intercept 8.87 + feature contributions = -227.296 (log-odds).
Score = sigmoid(-227.296) = 0.

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.246−7.674
Indentation frequencyHow rapidly indentation changes from line to line.219+6.838
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.219−4.605
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.244.902+3.013
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.121.98−1.501
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.121.992+1.164
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.074+0.222

Intercept 0.07 + feature contributions = -2.473 (log-odds).
Score = sigmoid(-2.473) = 0.078.

Score0.572
Score160
Run 1

The code has decent organization with clear class structure and method separation, but suffers from several readability issues. The build_digest_header method is very long, deeply nested, and too procedural. Multiple similar functions (md5_utf8, sha_utf8, etc.) could be condensed — the code repeats itself with only the hash algorithm differing. The intent is somewhat clear for those familiar with HTTP Digest Auth, but the code is not beginner-friendly and uses many short variable names (KD, A1, HA2). Action granularity is mixed: some lines combine multiple operations, while others spread logically single actions over several lines. Reading flow is disrupted by the excessive 'XXX' comments, embedded type hints, and the overloaded __init__ signatures. The use of walrus operators adds brevity but reduces readability. While the code is not unreadable, a refactor with helper methods, reduced repetition, and clearer variable naming would improve maintainability.

Run 2

The code is structured into logical methods with clear responsibilities, but readability suffers from inconsistent type annotations, excessive inline comments marking incomplete features ('XXX'), and repetitive lambda definitions within `build_digest_header`. The nesting is moderate, though the long if-elif chain for algorithms could be simplified. Intent is mostly clear due to descriptive method names and comments, but ambiguous practices like redefining `HA1` based on algorithm and using `entdig` without implementation reduce clarity. Code length is reasonable but some segments (e.g., building `base` string) are verbose. Action granularity is adequate, with one operation per line in most places. Reading flow is mostly natural, but disjointed state handling via `_thread_local` and multiple `cast()` calls interrupt comprehension. Overall, functional but not polished for readability.

Run 3

The code has some clear strengths: it follows a logical class structure, has minimal nesting, and contains helpful comments. The use of type hints and documentation improves clarity. However, readability is reduced by several factors. The `build_digest_header` method is very long and complex, performing many distinct tasks (algorithm selection, string parsing, hash generation, internal state manipulation) that could be broken into smaller helper methods for better action granularity. The `handle_401` method also mixes several responsibilities (rewinding body, parsing headers, preparing request) and has a slightly tangled flow. While conditions are mostly flat, the repeated lambda definitions for hashing functions are verbose and could be simplified. The use of walrus operators (`:=`) and `cast()` calls may reduce clarity for some readers. Variable names like `s`, `A1`, and `KD` are somewhat cryptic. The comment "XXX not implemented yet" suggests incomplete parts that make the intent ambiguous. Overall, the code is maintainable but could benefit from refactoring the larger methods and improving naming for better comprehension.

Run 1

Code Structure: Methods logically separate initialization, digest generation, response handling, and request setup, but build_digest_header combines several responsibilities. Nesting: Mostly shallow, with moderate nesting in algorithm selection and retry handling. Clarity of intent: Descriptive method names, type hints, and comments explain the authentication workflow; terse variables such as s, KD, and _r, outdated comments, and implicit thread-local state reduce clarity. Code length: Repeated hash wrappers, verbose state access, and placeholder logic make the implementation longer than necessary. Action granularity: Generally one action per line, although assignment expressions combine lookup and condition checking, and r.content triggers a non-obvious side effect. Reading flow: The sequence from challenge parsing through digest construction to request retry is coherent, but the long digest-building method and cross-method state dependencies require careful tracking.

Run 2

Code Structure: Methods logically separate initialization, digest generation, response handling, and request preparation, although digest generation combines several responsibilities. Nesting: Mostly shallow conditionals and early returns keep control flow manageable; nested hash helpers add some complexity. Clarity of intent: Descriptive method names, annotations, and explanatory comments communicate the authentication workflow, but cryptic variables such as s, KD, and respdig, implicit thread-local state, and outdated comments reduce clarity. Code length: Repeated hashing helpers and the lengthy digest-building method could be simplified; unused imports and placeholder logic add noise. Action granularity: Almost every line performs a single action, making state changes and request preparation easy to follow. Reading flow: The sequence generally follows the authentication lifecycle naturally, but understanding protocol-specific calculations and tracing shared state across hooks require extra effort.

Run 3

Code Structure: Methods logically separate initialization, digest generation, response handling, and request setup, though digest generation combines several responsibilities. Nesting: Mostly shallow, with early returns reducing complexity; nested hash helpers and retry handling add moderate depth. Clarity of intent: Descriptive method names, type annotations, and protocol comments help, but terse variables such as s, KD, and _r, implicit thread-local state, and an outdated lambda comment reduce clarity. Code length: Reasonable for the protocol complexity, but repeated hashing helpers and lengthy header construction could be simplified. Action granularity: Generally one action per line; assignment expressions remain manageable, although the standalone r.content access has a non-obvious side effect. Reading flow: Follows a natural authentication sequence with useful spacing, but long methods, scattered state mutations, and unused imports interrupt the flow.