Skip to content

Library logs through the root logger — use a module-level named logger instead #80

Description

@pulse-mind

FYI : This has been generated by AI

Use a named module-level logger instead of root logger in h4d.py

Summary

html4docx/h4d.py emits all its warnings via the module-level logging functions (logging.warning(...)), which write to the root logger. As a library, this is problematic: consumers cannot raise the verbosity or silence these messages without affecting their entire application logging, because there is no dedicated logger name to target in their logging config.

Why this matters

In a Django (or any framework) LOGGING config, you normally silence a noisy dependency with:

"loggers": {
    "html4docx": {"level": "ERROR", "propagate": False},
},

This currently has no effect, because the records are created on the root logger, not on an html4docx-namespaced logger. In production we get hundreds of lines like:

WARNING ... Unrecognized paragraph style 'letter-spacing', will be skipped.
WARNING ... Unrecognized paragraph style 'margin', will be skipped.
WARNING ... Unrecognized paragraph style 'padding', will be skipped.

for every HTML→DOCX conversion (these CSS properties are very common), and there is no clean way to filter them out short of attaching a custom logging.Filter on a handler and matching record.module == 'h4d' — which is fragile.

Affected version

1.1.5

Proposed fix

Define a module-level named logger and route every logging.<level>(...) call through it.

1. Near the top of html4docx/h4d.py (after the import logging on line 2):

logger = logging.getLogger(__name__)

This gives the logger the name html4docx.h4d, so consumers can configure html4docx (parent) or html4docx.h4d directly.

2. Replace the 14 logging.<level>(...) calls with logger.<level>(...). Affected lines in h4d.py (v1.1.5):

Line Current
531 logging.warning(f"Warning: Unrecognized style '{style_name}', will be skipped.")
551 logging.warning(f"Warning: Unrecognized paragraph style '{style_name}', will be skipped.")
712 logging.warning(f"Warning: Could not parse font-size '{font_size}': {e}")
761 logging.warning(f"Warning: Could not apply font-family '{font_family}': {e}")
788 logging.warning(f"Could not apply color '{color_value}': {e}")
826 logging.warning(f"Warning: Unsupported text transform '{text_transform}'")
829 logging.warning(f"Warning: Could not apply text-transform '{text_transform}': {e}")
923 logging.warning(f"Warning: Unsupported text decoration '{text_decoration_line}'")
945 logging.warning(f"Warning: Style not recognized'{text_decoration_style}', defaulting to single line.")
976 logging.warning(f"Warning: Unsupported background color '{background_color}'")
996 logging.warning(f"Could not apply background-color to paragraph: {e}")
1005 logging.warning(f"Warning: Unsupported background color '{background_color}'")
1027 logging.warning(f"Could not apply background-color to run: {e}")
1513 logging.warning(f"Warning: Custom style '{custom_style}' not found in document, Ignoring style.")

i.e. logging.warning(...)logger.warning(...). A single search-and-replace of logging.warning(logger.warning( within h4d.py covers all of them.

Notes

  • This is fully backwards-compatible: by default the records still propagate to the root logger, so existing behaviour is unchanged. It only adds the ability to configure them.
  • The CLI entry point (argparse/__main__) can keep a logging.basicConfig(...) call so command-line users still see output.
  • Optionally, since "unrecognized style" messages are expected for any non-trivial CSS, consider downgrading the recurring ones (lines 531/551) from warning to debug — they describe normal, non-actionable skips rather than problems.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions