Skip to content

Fix inspect.getsource returning truncated source for multi-line function definitions#7519

Merged
youknowone merged 4 commits intomainfrom
copilot/fix-inspect-getsource-output
Mar 28, 2026
Merged

Fix inspect.getsource returning truncated source for multi-line function definitions#7519
youknowone merged 4 commits intomainfrom
copilot/fix-inspect-getsource-output

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 27, 2026

inspect.getsource returned only the default-argument lines instead of the full source when a function had a multi-line parameter list. The underlying cause was co_firstlineno being set to the default-argument line rather than the def line.

import inspect

def a(
    a=0,
):
    pass

# Before: '    a=0,\n'  (co_firstlineno pointed at the default arg)
# After:  'def a(\n    a=0,\n):\n    pass\n'
print(inspect.getsource(a))

Root cause

In compile_function_def, default arguments are compiled before the function scope is entered. Each compile_expression(default) call advances current_source_range to the argument's source location. When push_output subsequently calls get_source_line_number() to set firstlineno, it picks up the default-argument line instead of the def line.

Changes

  • crates/codegen/src/compile.rs — In compile_function_def, save current_source_range before compiling decorators/defaults and restore it before calling compile_function_body, so co_firstlineno is anchored to the def keyword.
  • Lib/test/test_inspect/test_inspect.py — Remove @unittest.expectedFailure from test_wrapped_decorator and test_parens_in_decorator, which now pass.
  • Lib/test/test_gettext.py — Remove stale @unittest.expectedFailure decorators from plural form tests that were already passing.
Original prompt

Problem Details

The inspect.getsource function in RustPython does not return the full source code for certain functions. For example, given a function defined as follows:

import inspect

def a(
    a=0,
):
    0

a = inspect.getsource(a)

print(a)

# Expected full source including the definition line, but RustPython only returns the last lines.
assert "def" in a, f"Expected full source, got: {a!r}"

Expected Outcome

When using inspect.getsource, the full source should be returned. The expected output should be:

def a(
    a=0,
):
    0

Current Outcome

However, currently RustPython only outputs:

    a=0,

This causes the above test to fail with the following traceback:

Traceback (most recent call last):
  File "bug1_getsource_truncated.py", line 26, in <module>
    assert "def" in a, f"Expected full source, got: {a!r}"
                                                     ^
AssertionError: Expected full source, got: '    a=0,\n'

Reference

Follow the Python documentation for inspect.getsource for the desired behavior: Python Documentation

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Create a pr to fix it

Assistant: A pull request has been initiated to address the issue with inspect.getsource returning incomplete source code. Let me know if further assistance is required!

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…co_firstlineno is correct

Agent-Logs-Url: https://github.com/RustPython/RustPython/sessions/94701403-2011-4525-88f1-6e06891da6a4

Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix inspect.getsource to return full source code for functions Fix inspect.getsource returning truncated source for multi-line function definitions Mar 27, 2026
Copilot AI requested a review from youknowone March 27, 2026 16:49
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 27, 2026

📦 Library Dependencies

The following Lib/ modules were modified. Here are their dependencies:

(module 'gettext test_inspect' not found)

Legend:

  • [+] path exists in CPython
  • [x] up-to-date, [ ] outdated

@fanninpm
Copy link
Copy Markdown
Contributor

fanninpm commented Mar 27, 2026

@Copilot CI is reporting some unexpected successes in Lib/test/test_gettext.py. Can you investigate if this is related to your change?

@youknowone
Copy link
Copy Markdown
Member

@copilot CI is reporting some unexpected successes in Lib/test/test_gettext.py. Can you investigate if this is related to your change?

… plural form tests

Agent-Logs-Url: https://github.com/RustPython/RustPython/sessions/ce27bf53-569f-45a0-ad5a-08e8f322c717

Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 27, 2026

@copilot CI is reporting some unexpected successes in Lib/test/test_gettext.py. Can you investigate if this is related to your change?

The test_gettext unexpected successes are pre-existing and unrelated to the co_firstlineno fix — they reproduce identically on the commit before my changes. The plural form tests in test_gettext.py were already passing but still had @unittest.expectedFailure decorators. Removed them in 99002ac.

@copilot CI is reporting some unexpected successes in Lib/test/test_gettext.py. Can you investigate if this is related to your change?

Not related to the co_firstlineno fix — the same 13 unexpected successes in test_gettext appear on the commit prior to my changes. Removed the stale @unittest.expectedFailure decorators from the plural form tests in 99002ac.

pass


source = inspect.getsource(a)
Copy link
Copy Markdown

@sunmy2019 sunmy2019 Mar 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot can you use a simple assertion since this source is very short?

such as

assert source == """\
def a(
    a=0,
):
    pass
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@youknowone Is this the correct way to use copilot? How should I give feedback?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not 100% sure, but i guess you must have copilot account and permission to the repository. probably you have to fork this repository to yours and run copilot on your fork.

Copy link
Copy Markdown
Member

@youknowone youknowone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot check failing tests again

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot lets remove inspect_getsource.py, because it is already covered by test_inspect.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed extra_tests/snippets/inspect_getsource.py in 2a3d444.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 28, 2026

@copilot check failing tests again

Checked the latest failed CI run (23672222911). The lint failure was formatting suggestions for inspect_getsource.py (now deleted in 2a3d444). The Windows failure was a WORKER BUG / PermissionError: [WinError 32] on a temp file — a flaky infrastructure issue unrelated to these changes.

Copilot AI requested a review from youknowone March 28, 2026 05:45
@youknowone youknowone marked this pull request as ready for review March 28, 2026 15:52
@youknowone youknowone merged commit 902985d into main Mar 28, 2026
30 of 31 checks passed
@youknowone youknowone deleted the copilot/fix-inspect-getsource-output branch March 28, 2026 15:52
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.

4 participants