Skip to content

py/objtype: Validate that __len__ returns an int. - #19647

Open
pablogventura wants to merge 4 commits into
micropython:masterfrom
pablogventura:py-len-validate-type
Open

py/objtype: Validate that __len__ returns an int.#19647
pablogventura wants to merge 4 commits into
micropython:masterfrom
pablogventura:py-len-validate-type

Conversation

@pablogventura

@pablogventura pablogventura commented Aug 24, 2026

Copy link
Copy Markdown

Summary

Fixes #19512. instance_unary_op already validates that __hash__ / __int__ return an int, but MP_UNARY_OP_LEN fell through unchecked, so len(obj) could return None / str / float.

Fold MP_UNARY_OP_LEN into the existing MP_UNARY_OP_INT_MAYBE arm (approach from @jseop-lim on the issue). Non-int __len__ results raise TypeError. This also covers callers that go through instance unary_op.

Testing

  • tests/basics/builtin_len_user.py (int OK; None / str / tuple -> TypeError)
  • tests/run-tests.py basics/builtin_len_user.py on unix standard and minimal

Trade-offs and Alternatives

Code size (unix standard, clean rebuild, size text section):

Version bytes vs master
master 796150 -
this commit 796150 0

instance_unary_op in objtype.o grows by 8 bytes; the linked binary text is unchanged (section padding).

Does not reject a negative __len__ (not free; left for a separate discussion as on the issue).

Deliberate divergence vs CPython: __len__ returning bool raises TypeError here (mp_obj_is_int excludes bool), same as __int__ / #19203. Not covered in the test so the harness can compare against CPython.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.

pablogventura and others added 2 commits August 24, 2026 11:12
Fold MP_UNARY_OP_LEN into the existing INT_MAYBE arm so a non-int
__len__ result raises TypeError, matching the zero-cost approach
discussed in micropython#19512.

Co-authored-by: Jeongseop Lim <jseoplim@gmail.com>
Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Keep the test runnable on the unix minimal variant (no float
literals, no bytearray).

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown

Code size report:

Reference:  all: Bump version to 1.29.0. [0fd6c57]
Comparison: ci: Retrigger unix port after stackless_clang flake. [merge of a6a12f8]
  mpy-cross:   +16 +0.004% 
   bare-arm:    +4 +0.007% 
minimal x86:    +5 +0.003% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +4 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +6 +0.001% VIRT_RV32

@codecov

codecov Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.55%. Comparing base (0fd6c57) to head (a6a12f8).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19647      +/-   ##
==========================================
- Coverage   98.58%   98.55%   -0.04%     
==========================================
  Files         182      182              
  Lines       23322    23322              
  Branches        5        5              
==========================================
- Hits        22993    22985       -8     
- Misses        328      336       +8     
  Partials        1        1              
Flag Coverage Δ
unix-coverage-32bit 98.55% <ø> (-0.04%) ⬇️
unix-coverage-64bit 98.52% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
@dpgeorge dpgeorge added py-core Relates to py/ directory in source board-definition New or updated board definition files. Combine with a port- label. and removed board-definition New or updated board definition files. Combine with a port- label. labels Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

py-core Relates to py/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

len() does not validate the value returned by __len__

2 participants