Skip to content

Bug: inspect.getframeinfo fails in blingfire/__init__.py when imported within timeit or certain contexts #191

@speedyk-005

Description

@speedyk-005

Description

When importing blingfire (v0.1.8 or v0.2.1) within certain runtime contexts, specifically:

  • Inside timeit.repeat() lambda functions
  • Inside pydantic validate wrappers

The import fails with:

...
File "/home/spdk/projects/chunklet-py/.venv/lib/python3.12/site-packages/blingfire/__init__.py", line 8, in <module>
    filename = inspect.getframeinfo(inspect.currentframe()).filename
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 1718, in getframeinfo
    lines, lnum = findsource(frame)
                  ^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 1090, in findsource
    module = getmodule(object, file)
             ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 1013, in getmodule
    f = getabsfile(module)
        ^^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 982, in getabsfile
    _filename = getsourcefile(object) or getfile(object)
                ^^^^^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 958, in getsourcefile
    if any(filename.endswith(s) for s in all_bytecode_suffixes):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/spdk/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/inspect.py", line 958, in <genexpr>
    if any(filename.endswith(s) for s in all_bytecode_suffixes):
           ^^^^^^^^^^^^^^^^^
AttributeError: 'function' object has no attribute 'endswith'

Steps to Reproduce

import timeit
from blingfire import text_to_sentences

text = "Hello world. How are you?" * 10

# This will fail
t = min(timeit.repeat(lambda: text_to_sentences(text), number=10, repeat=5)) * 1000

Root Cause

In blingfire/__init__.py line 8:

filename = inspect.getframeinfo(inspect.currentframe()).filename

The issue is in Python's inspect.getsourcefile() which tries to get the source file of a function object, but in certain contexts (timeit, pydantic wrappers) the object passed is a function rather than a module, causing endswith to fail.

Expected Fix

Replace the inspect-based filename detection with a more robust approach:

# Option 1: Use __file__ directly
from blingfire import __file__ as filename

# Option 2: Catch the AttributeError and fallback
try:
    filename = inspect.getsourcefile(blingfire)
except AttributeError:
    filename = blingfire.__file__

Environment

  • Python 3.12
  • blingfire 0.1.8 / 0.2.1
  • Linux x86_64

Additional Context

This bug does NOT occur when calling text_to_sentences() directly outside of timeit. It only fails in specific runtime introspection contexts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions