Sample

pyint-911a9744e2cf-I10

Deterministically remove some optional blank lines and bracketed line breaks

Matched original source

Lines224

Scores

MethodScoreScale
Posnett00–1; higher is more readable
Dorn0.0950–1; higher is more readable
Mi0.4110–1; higher is more readable
LLOC160Logical lines; fewer is more readable
DeepSeek V4 Pro11.670–20; mean of three runs
GPT-6.1 Sol14.330–20; mean of three runs
BTTF0.3170–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.224+89.6
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.496−6.743

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

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.225−6.93
Indentation frequencyHow rapidly indentation changes from line to line.199+6.146
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.199−4.146
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.223.854+2.719
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.987−1.502
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.121.982+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.257 (log-odds).
Score = sigmoid(-2.257) = 0.095.

Score0.411
Score160
Run 1

The code has several readability challenges. The class structure is somewhat organized, but methods like build_digest_header are long and contain deeply nested conditional logic. While the action granularity is generally one operation per line, some lines are overly long with awkward formatting (e.g., the `base = (` multi-line string, and the broken `_digest_auth = self.build_digest_header(` call). The intent is partially clear from comments and method names like handle_401 and handle_redirect, but complex digest logic lacks explanatory comments for branches. Type hints are helpful but contribute to clutter in some places. The reading flow is interrupted by inconsistent spacing, multi-line function calls, and abrupt method transitions without blank lines. Nesting depth is moderate but still increases cognitive load. Overall, the code needs structural refactoring, more consistent style, and extraction of complex logic into smaller functions to improve readability.

Run 2

The code has reasonable structure but suffers from inconsistent formatting, overly long methods, and some deeply nested logic. The build_digest_header method is particularly long with repetitive if/elif blocks, making it hard to follow. There are awkward line breaks, misaligned indentation, and spacing issues throughout. While naming is generally clear and intent is mostly understandable, the digest authentication logic is complex and the implementation doesn't do enough to break it down. The handle_401 and __call__ methods have moderate nesting but some lines combine multiple operations. Action granularity is occasionally violated. The reading flow is disrupted by formatting inconsistencies and the nested functions. Some comments are helpful, but they're not enough to compensate for the overall readability issues.

Run 3

The code is moderately readable but has several issues. The class has clear purpose and type hints, but method definitions lack spacing between them, hurting visual separation. Nested functions inside build_digest_header create multiple duplication (md5_utf8, sha_utf8, etc.) and make the logic harder to follow. The base string construction has awkward formatting with excessive whitespace and misaligned parentheses. Some lines are overlong (f-strings with many interpolations), reducing scannability. The action granularity is mixed: most lines do one thing, but some combine multiple operations (e.g., s += nonce.encode('utf-8')). The reading flow is disrupted by formatting inconsistencies and the `_thread_local` access pattern repeating frequently without abstraction. The use of walrus operators in conditionals adds cognitive load. Overall, the code is maintainable by someone familiar with HTTP digest auth but not immediately clear to a general reader. Deduplicating hash function definitions and improving spacing/line breaks would raise readability significantly.

Run 1

Code Structure: Responsibilities are sensibly separated into initialization, digest construction, response handling, and request hooks, though digest construction does too much. Nesting: Mostly shallow, with moderate nesting in algorithm selection and authentication retry handling. Clarity of intent: Descriptive method names, type hints, and explanatory comments help; terse protocol variables, stale comments, and implicit thread-local state make some details harder to follow. Code length: Generally justified by the protocol, but repeated hashing helpers and unused imports add clutter. Action granularity: Most lines perform one action; assignments inside conditions and the standalone r.content access require extra interpretation. Reading flow: Processing follows a logical sequence, but inconsistent spacing, missing blank lines between methods, and awkwardly formatted calls interrupt scanning.

Run 2

Code Structure: Methods separate initialization, digest generation, response handling, and request preparation logically, although digest generation combines several responsibilities. Nesting: Mostly shallow, with manageable nested conditionals and local hash functions. Clarity of intent: Descriptive method names, annotations, and protocol comments help; abbreviated variables such as s, KD, and _r, misleading comments, and unexplained state obscure details. Code length: Reasonable for the functionality, but repeated hash wrappers, unused imports, and placeholder logic add clutter. Action granularity: Generally one action per line; assignment expressions slightly increase cognitive load but remain localized. Reading flow: Authentication steps follow a coherent sequence, but inconsistent spacing, missing blank lines between methods, awkward line wrapping, and frequent thread-local accesses interrupt scanning.

Run 3

Code Structure: Methods logically separate initialization, digest construction, response handling, and request preparation, but digest construction combines several responsibilities. Nesting: Mostly shallow, with early returns limiting depth; nested hash functions and authentication branches add complexity. Clarity of intent: Descriptive method names, type hints, and explanatory comments help, but abbreviated variables, implicit thread-local state, and outdated comments obscure details. Code length: Repeated hash wrappers and lengthy digest construction introduce avoidable verbosity. Action granularity: Generally one action per line; inline overload declarations and assignment expressions slightly compress operations without substantially impairing comprehension. Reading flow: Authentication steps follow a sensible sequence, but inconsistent blank lines, awkward spacing in multiline expressions, and sparse method separation interrupt scanning. Overall, readable to someone familiar with HTTP digest authentication, but formatting cleanup, clearer names, and helper extraction would improve accessibility.