Posts

Reject a path that escapes a temporary workspace

A workspace check must compare normalized paths, not merely look for .. in supplied text. This example creates a TemporaryDirectory , resolves its root, and then resolves two candidate paths. The first candidate enters reports , returns with .. , and ends at report.txt inside the workspace. The second ends at a sibling location and must be rejected. Path.relative_to() returns the child portion when its receiver is beneath the supplied base; otherwise it raises ValueError . The assertion therefore verifies the accepted candidate’s relative name, while the except branch explicitly records rejection of the escaping candidate. Path.resolve() is important here because it eliminates .. components and follows existing symbolic links before comparison. See the official pathlib documentation and relative_to reference . This is suitable for a Python 3.6+ baseline, which includes Path.resolve() . It is a path-validation step, not a complete authorization system. In particular, filesyst...

Round-trip an lzma-compressed text fixture

LZMA's standard-library module can create an XZ container directly from a byte string. Here, the concrete fixture is the UTF-8 text north followed by south , with a newline after each word. lzma.compress creates bytes in FORMAT_XZ , and lzma.decompress restores the payload from those bytes. The example selects CHECK_CRC64 , the documented default integrity check for the XZ format, explicitly so the format choice is visible in the fixture. It then asserts the XZ signature, byte-for-byte restoration, and the decoded line sequence. The signature assertion only identifies the expected container prefix; it neither validates every archive property nor makes untrusted compressed input safe to process. A round-trip test also cannot establish a bound on decompression memory use for arbitrary inputs. lzma.decompress defaults to automatic recognition of XZ and legacy .lzma containers, but the explicit compression format makes this test's output contract clear. The module was added...

Explain DST fold ambiguity with two explicit instants

Explain DST fold ambiguity with two explicit instants During the 2020 autumn DST transition in Los Angeles, the local clock displayed 01:30 twice. Starting with explicit UTC instants removes any ambiguity: 08:30 UTC converts to 2020-11-01T01:30:00-07:00 , while 09:30 UTC converts to 2020-11-01T01:30:00-08:00 . They share the same wall-clock fields but have different offsets and fold values. fold=0 identifies the earlier occurrence and fold=1 the later occurrence. The example derives both local values from UTC, then asserts their wall-clock portions match, their folds differ, and the source instants are one hour apart. That last assertion is made on the UTC values: comparisons or subtraction between aware datetimes that share a tzinfo object have rules that can be surprising around a fold. Treat the UTC instant, or another unambiguous stored representation, as the value used to order events. ZoneInfo supplies IANA timezone rules, so this result depends on the available timezone ...

Find a relative path below a known root

Find a relative path below a known root When a program already knows a root directory, Path.relative_to can express a descendant without repeating that root. The temporary fixture creates project/src/api.py . Calling file_path.relative_to(root) removes the project portion and returns the relative path src/api.py . This is useful when a manifest, log entry, or comparison should be scoped to a known project rather than expose an absolute location. The assertions check both directions relevant to the controlled fixture: the derived path has the expected components, and joining it to this root recreates the original path. as_posix() is used only for output, giving forward slashes on every platform and avoiding the randomly generated temporary-directory name. pathlib was introduced in Python 3.4, and this exact recipe requires Python 3.5+ because it calls Path.write_text . With the default walk_up=False , relative_to raises ValueError when the candidate does not begin with the sup...

Build a rolling seven-day date range

A rolling date window should be anchored to an explicit reporting date rather than to date.today() . That makes scheduled reports reproducible and makes tests independent of the machine clock. In this example, the input is 2025-03-10 , interpreted as the inclusive end of the range. Subtracting six calendar days gives the inclusive start, so the generated list contains exactly seven dates: March 4 through March 10. datetime.date supports addition and subtraction with timedelta ; date arithmetic uses the delta’s whole-day component. timedelta(weeks=1) is seven days, but this task needs an inclusive seven-item list, so range(7) makes the boundary rule visible. The assertions verify both endpoints and the item count for this specific input. They do not prove that the surrounding reporting system has chosen the intended timezone or business-day definition. Use date values when the requirement is calendar-based. If the anchor begins as an instant, first decide which timezone determines...

Represent a date-only deadline without a time component

A deadline expressed as “2026-06-30” contains a calendar day, not a clock time. Represent it with datetime.date : its value has year, month, and day components only. In the example, date.fromisoformat() parses the input string and subtracting today produces a timedelta of two days. Printing isoformat() returns the unambiguous date-only representation. Avoid encoding a date-only rule as midnight in an arbitrary time zone unless the product also defines what happens at that boundary. A midnight datetime adds a time component, a zone decision, and potentially daylight-saving behavior that the original rule did not state. If a later workflow needs a timestamp, make the conversion at that workflow boundary with an explicitly documented time zone and policy. The assertions verify the supplied synthetic values and the result of standard date arithmetic. They do not establish whether a deadline is inclusive, whether it is a business day, or which instant ends that date for a particular...

List ZIP member names without extracting

A ZIP archive can be inspected without placing any of its members on the filesystem. Here, a temporary archive is populated with two entries: docs/guide.txt and src/main.py . After reopening it in the default read mode, namelist() returns archive member names in archive order. The program asserts that order and then prints each name. No call to extract() or extractall() occurs. The example therefore demonstrates listing metadata, not recovering either member’s contents. namelist() returns names rather than ZipInfo records; use infolist() when attributes such as uncompressed size or CRC are needed. A name is archive metadata, not proof that it is suitable to extract or that its contents are trustworthy. In particular, inspect and validate names before designing an extraction workflow for an archive from an untrusted source. This code requires Python 3.6.2+ because ZipFile receives a pathlib.Path . ZipFile.namelist() itself is an established API rather than a newer-version fea...