Skip to content

fix: handle non-Text nodes in Text.__getitem__ - #352

Open
kshivam4781 wants to merge 2 commits into
K1rL3s:masterfrom
kshivam4781:kshivam4781-patch-1
Open

kshivam4781 wants to merge 2 commits into
K1rL3s:masterfrom
kshivam4781:kshivam4781-patch-1

Conversation

@kshivam4781

@kshivam4781 kshivam4781 commented Sep 21, 2026 •

Copy link
Copy Markdown

Описание

Text.__getitem__ raised TypeError for any node that was neither str nor Text (e.g. int, float), even though Text.__init__ accepts arbitrary NodeType (= Any) and render() already treats any non-Text node as str(node):

Text(123, "abc")[0:2]  # TypeError: object of type 'int' has no len()

The size computation only branched on str vs "everything else" and called len(node) for non-str nodes, which fails for objects (like int) that don't implement __len__.

Note on the fix vs. the issue's suggested one-liner: node_size = len(node) if isinstance(node, Text) else sizeof(str(node)) alone isn't quite enough, because the slicing branch further down (new_node = node[a:b] for the non-str case) would still raise on a non-Text node - 123[a:b] isn't subscriptable either. So the fix normalizes any non-Text node to str(node) once, up front (mirroring exactly what render() already does), and both the size computation and the slicing branch fall out correctly from that single normalization.

Closes #305

Тип изменения

  • Документация (опечатки, примеры кода или любые другие обновления документации)
  • Исправление бага (некритическое изменение, которое устраняет проблему)
  • Новый функционал (некритическое изменение, добавляющее функциональность)
  • Критические изменения (исправление или функционал, из-за которого существующая функциональность не будет работать должным образом)
  • Это изменение требует обновления документации

Как это было протестировано?

Added 5 regression tests in tests/maxo/utils/test_formatting.py::TestGetItemNonTextNode: a slice spanning across an int node into a following str node, a slice landing entirely inside the stringified int node, a slice starting after the int node, a float node (to confirm this isn't int-specific), and the full-slice fast path (node[:]), which must leave _body untouched (not pre-stringified).

Confirmed the new tests fail against the pre-fix code (TypeError: object of type 'float' has no len()) and pass after the fix, so they're real regression tests, not tautologies.

Ran locally:

  • uv run pytest tests/ --cov=src --cov-report=term -> 1840 passed, src/maxo/utils/formatting.py at 100% coverage
  • uv run ruff check --no-fix . -> clean
  • uv run black --check . -> clean
  • uv run mypy --config-file pyproject.toml -> clean
  • uv run slotscheck -m maxo -> All OK
  • uv run codespell src examples -> clean

Тестовая конфигурация:

  • Операционная система: Linux
  • Версия Python: 3.12.3 (project supports 3.12 / 3.13 / 3.14)

Контрольный список:

  • Мой код соответствует рекомендациям по стилю этого проекта
  • Я выполнил самопроверку своего кода
  • Я внёс соответствующие изменения в документацию (не требуется - внутренний багфикс, публичный API не менялся)
  • Я добавил тесты, которые доказывают, что моё исправление эффективно или моя функция работает
  • Новые и существующие модульные тесты проходят локально с моими изменениями
  • Код полностью написан мной без использования нейросетей
  • Код частично или полностью написан нейросетями, но прошёл полный контроль со стороны человека

Summary by CodeRabbit

  • Исправления
    • Исправлена нарезка текста, содержащего числовые и другие нестроковые элементы: теперь она корректно выполняется по их строковому представлению.
    • Улучшена обработка срезов для целых чисел, дробных чисел и объектов других типов.
  • Тесты
    • Добавлены проверки нарезки нестроковых элементов, включая границы и полный срез.

node_size computation only handled str via sizeof() and fell back to len(node) for everything else, but Text.__init__ accepts arbitrary NodeType (Any) and render() converts any non-Text node via str(node). len(node) then raised TypeError for int/float/etc. Fixes K1rL3s#305.
@coderabbitai

coderabbitai Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Understand this PR’s impact

Explore downstream dependencies and potential security impact with Blast Radius.

View blast radius →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 73da2cd4-5519-4585-afcf-bfb4190b8bc1

📥 Commits

Reviewing files that changed from the base of the PR and between d31f41a and 449fe7b.

📒 Files selected for processing (2)
  • src/maxo/utils/formatting.py
  • tests/maxo/utils/test_formatting.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Изменена нарезка Text для нестроковых узлов. Такие узлы преобразуются в строки при вычислении размера. Добавлены тесты для int, float и полного среза без предварительного преобразования.

Changes

Нарезка Text

Layer / File(s) Summary
Обработка и проверка нестроковых узлов
src/maxo/utils/formatting.py, tests/maxo/utils/test_formatting.py
Text.__getitem__ использует sizeof(str(node)) для нестроковых узлов. Тесты проверяют срезы int и float, а также сохранение исходного узла при полном срезе.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: k1rl3s

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок кратко и точно описывает основной багфикс: обработку узлов, не являющихся Text, в Text.getitem.
Description check ✅ Passed Описание соответствует шаблону. Оно содержит проблему, мотивацию, ссылку на issue, тип изменения, подробности тестирования, конфигурацию и заполненный контрольный список.
Linked Issues check ✅ Passed Требование issue #305 выполнено. В Text.__getitem__ узлы Text обрабатываются через len(node), а остальные узлы сначала преобразуются через str(node) и измеряются через sizeof. Это согласует …
Out of Scope Changes check ✅ Passed Изменения остаются в рамках issue #305. PR изменяет только расчёт размера узлов в src/maxo/utils/formatting.py и добавляет связанные регрессионные тесты в tests/maxo/utils/test_formatting.py. Неза…
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text.__getitem__ падает TypeError на не-строковых узлах

1 participant