getLogger() now assigns manager on newly created loggers so
isEnabledFor can check manager.disable. When replacing a Placeholder,
_fixupParents is also called to establish the parent chain. clear()
skips Placeholder entries that lack a clear method.
Added browser-compatible Writable interface with ConsoleWritable and
StderrWritable implementations. StreamHandler.emit() writes to a
Writable stream. ConsoleHandler maps levels to console.warn/error/log.
StderrHandler emits via console.error. FileHandler throws on
construction in browser. Handler.handleError() logs diagnostics.
Writable interface designed for extensibility (issue 13).
Define Writable interface, ConsoleWritable (console.log), and
StderrWritable (console.error) as browser-safe stream abstractions.
Export DEFAULT_STREAM backed by StderrWritable to match Python's
sys.stderr default.
Implement StreamHandler.emit(), ConsoleHandler for browser console
API, and a browser-compatible stream abstraction. Design handler
base with issue 13 (localStorage handler) in mind.
Implemented %-style field substitution in PercentFormatterStyle,
JS Date-based formatTime with strftime token support and ISO8601
fallback, Error.stack-based formatError, and LogRecord.getMessage.
Added message, name, msg, args fields to LogRecord.
Cover %-style substitution with %(name)s, %(levelno)d, %(levelname)s,
multiple placeholders, unknown field errors, asctime population,
ISO8601 and custom datefmt time formatting, Error.stack formatting,
usesTime detection, and LogRecord.getMessage with %s arg substitution.
PercentFormatterStyle._format() now performs %(key)s/d/f substitution
against LogRecord attributes. Formatter.format() sets record.message
via getMessage() and conditionally calls formatTime() for asctime.
formatTime() uses JS Date with strftime-style tokens (%Y,%m,%d,%H,
%M,%S) or ISO8601 fallback. formatError() returns Error.stack.
BASIC_FORMAT updated to use %(levelname)s. Fixed datefmt type in
config.ts.
Implement PercentFormatterStyle._format() with %-style field
substitution, Formatter.formatTime() using JS Date/Intl, and
Formatter.formatError() using Error.stack. Add datetime helpers.
Added info(), warning(), error(), and critical() methods to Logger,
each gated by isEnabledFor(). All level methods tested including
effective level filtering.
Fixed logic bugs across manager, config, logger, handler, and
formatter modules. Manager.getLogger() now correctly creates and
returns loggers with hierarchy setup. Config.basicConfig() reads
the correct option fields and has proper control flow. Logger
isEnabledFor() caches correctly, _log() calls handle(), makeRecord()
uses Object.keys(). Handler has working formatter getter, format()
returns a string, and level setter no longer recurses. Formatter
has a format() method. Added unit tests for all four modules.
Add format() method to Formatter class to delegate to the style's
format method. Change Placeholder.loggers to public so Manager can
access it for hierarchy fixup.
Fix dateformat and style variables reading from wrong option fields
(filemode instead of datefmt/style). Restructure control flow to
match CPython logic: early return when handlers exist and force is
not set, proper mutual exclusion of stream/filename/handlers args.
Remove unreachable code block.
Fix isEnabledFor() to correctly cache and return level check results
instead of always caching false. Fix _log() to call handle() after
creating the LogRecord. Fix makeRecord() to use Object.keys() and
template literal. Add manager getter and fix setter to actually
assign the value.
Add missing getter for formatter property. Fix format() to return
the formatted string instead of discarding it. Fix level setter
to assign to _level instead of recursing infinitely.
Fix inverted type check in getLogger() and add missing return
statement. Implement _fixupParents() and _fixupChildren() to
establish parent-child logger relationships based on dot-separated
scope names.
Bitbucket Pipelines has some weird default behavior on how artifacts are
archived and JUnit test-reports are parsed on every subsequent run, if the
output was once an artifact. It's confusing to look at via the dashboard, hence
I'm adding an override to remove them beforehand.