GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Verify support for Python 3.15 by amotl · Pull Request #2 · dlt-contrib/dlt-filesystem Conversation
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Caution Review failedThe pull request is closed. Finishing Touches
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. Comment |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
CI failures: stale base, not the 3.15 change The branch is on
Rebasing on The next blocker on 3.15 is duckdb: 1.5.6 has no cp315 wheel yet, so the job will try a full source build. Keep 3.14 in the matrix and add 3.15 next to it until duckdb ships 3.15 wheels? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Thank you. Yes, let's wait for duckdb having compatible binary wheel packages published. Thank you for creating a ticket about it already, @eavanvalkenburg. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
3d4f192 to
03f4c0d
Compare
b94439a to
0d650b2
Compare
There was an error while loading. Please reload this page.
|
CI run #39690369174 reveals that validation on Python 3.15 does not succeed yet. However, we haven't been able identify the root cause: The process gets cancelled with no obvious error message or other hints about it. @hampsterx or @coderabbitai: Can you find any clues why this goes south? I have re-ran the CI workflow three times already, so I'd consider the job to be "deterministically failing" -- but why? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash set -uo pipefail echo '=== Run metadata ===' gh api repos/dlt-contrib/dlt-filesystem/actions/runs/39690369174 --jq '{id,head_sha,path,event,status,conclusion,run_attempt,created_at,updated_at,html_url}' echo '=== All jobs ===' gh api --paginate 'repos/dlt-contrib/dlt-filesystem/actions/runs/39690369174/jobs?filter=all&per_page=100' --jq '.jobs[] | {id,name,status,conclusion,started_at,completed_at,steps,html_url}' echo '=== Run log tail ===' gh run view 39690369174 --repo dlt-contrib/dlt-filesystem --log 2>&1 | tail -220 echo '=== Workflow file discovery ===' fd --hidden -t f -e yml -e yaml . .github Length of output: 47462 🏁 Script executed: #!/bin/bash set -uo pipefail echo '=== Workflow outline ===' ast-grep outline .github/workflows/tests.yml echo '=== Workflow content ===' cat -n .github/workflows/tests.yml for job in 119534795387 119536561745 119542386305; do echo "=== Job $job log tail ===" gh api "repos/dlt-contrib/dlt-filesystem/actions/jobs/$job/logs" | tail -150 echo "=== Job $job check annotations ===" check_url=$(gh api "repos/dlt-contrib/dlt-filesystem/actions/jobs/$job" --jq .check_run_url) if [ -n "$check_url" ] && [ "$check_url" != null ]; then gh api "$check_url" --jq '{conclusion,output}' gh api "$check_url/annotations" --jq '.[] | {path,start_line,annotation_level,message}' fi done echo '=== Test configuration discovery ===' fd --hidden -t f '^(pyproject\.toml|Makefile|pytest\.ini|tox\.ini|conftest\.py)$' Length of output: 7452 🏁 Script executed: #!/bin/bash set -uo pipefail for job in 119534795387 119536561745 119542386305; do echo "=== Job $job log tail ===" gh api --allow-escape-sequences "repos/dlt-contrib/dlt-filesystem/actions/jobs/$job/logs" | tail -110 done echo '=== Project configuration outline ===' ast-grep outline pyproject.toml echo '=== Project configuration ===' cat -n pyproject.toml echo '=== Test fixture outline ===' ast-grep outline tests/conftest.py Length of output: 57115 🏁 Script executed: #!/bin/bash set -uo pipefail echo '=== URI test outline ===' ast-grep outline tests/test_util.py echo '=== URI test code ===' rg -n -C 30 'def test_requote_uri' tests/test_util.py echo '=== URI implementation discovery ===' rg -n -C 5 --type py 'def requote_uri|import .*requote_uri|from .* import.*requote_uri' . echo '=== Latest job log selected evidence ===' gh api --allow-escape-sequences repos/dlt-contrib/dlt-filesystem/actions/jobs/119542386305/logs | python -c ' import sys,re lines=sys.stdin.read().splitlines() pending={} for line in lines: if re.search(r"Python|requests==|urllib3==|coverage==|pytest.*==|Runner Image|Image:|Version:|Poe =>|worker|shutdown|Memory|memory|disk",line): print(line) result=re.search(r"\[gw\d+\].*?\b(PASSED|FAILED|SKIPPED|ERROR|XFAIL|XPASS)\s+(.*)",line) if result: pending.pop(result.group(2).strip(),None) else: test=re.search(r"\b(tests/\S+::.*)",line) if test: pending[test.group(1).strip()]=line print("=== Test starts without matching result (may include formatting mismatches) ===") for line in pending.values(): print(line) ' echo '=== Python 3.10 equivalent test output ===' gh api --allow-escape-sequences repos/dlt-contrib/dlt-filesystem/actions/jobs/119534795016/logs | grep -E 'sig=%80|Python 3|requests==|coverage==' Length of output: 11743 🏁 Script executed: #!/bin/bash set -uo pipefail echo '=== YAML test outline ===' ast-grep outline tests/format/test_yaml.py echo '=== Recursive alias test ===' rg -n -C 25 'def test_recursive_alias_raises_cleanly' tests/format/test_yaml.py echo '=== YAML codec discovery ===' fd -t f -i 'yaml' rg -n -C 5 --type py 'def .*yaml|safe_load|SafeLoader|RecursionError|recursive.alias' src tests/format/test_yaml.py for job in 119534795387 119536561745 119542386305 119534795016; do echo "=== Job $job YAML evidence ===" gh api --allow-escape-sequences "repos/dlt-contrib/dlt-filesystem/actions/jobs/$job/logs" | grep -Ei 'pyyaml==|test_recursive_alias|test_yaml.py|shutdown signal' | tail -35 done Length of output: 34167 🏁 Script executed: #!/bin/bash set -uo pipefail ast-grep outline src/dlt_filesystem/source/format/iterable_codec.py sed -n '1,115p' src/dlt_filesystem/source/format/iterable_codec.py sed -n '175,225p' src/dlt_filesystem/source/format/iterable_codec.py rg -n -C 8 'normaliz|def read_via_iterable' src/dlt_filesystem/source/format/iterable_codec.py | tail -145 Length of output: 17223
EvidenceIn each Python 3.15 attempt, worker
The same test passes in approximately one millisecond on Python 3.10. Worker See the latest failed job. Likely triggerAt Line 157 of a: &a [*a] The test expects normalization to terminate with This makes cyclic normalization the primary suspect, not DuckDB installation or the final URI test. Installation and standalone imports succeed. The logs do not prove why the runner shuts down. Memory exhaustion is a possible explanation, but there is no OOM diagnostic in the retrieved logs. A Python 3.15 or coverage interaction also remains unverified. Next diagnostic checkIn the Python 3.15 environment, run only this test without parallel workers. Use an external timeout to bound the run: timeout --kill-after=5s 60s \
python -m pytest -o addopts='' -vv \
-o faulthandler_timeout=15 \
tests/format/test_yaml.py::test_recursive_alias_raises_cleanlyThen repeat with coverage enabled: timeout --kill-after=5s 60s \
python -m pytest -o addopts='' -vv --cov \
-o faulthandler_timeout=15 \
tests/format/test_yaml.py::test_recursive_alias_raises_cleanlyThese checks should capture a stack trace before shutdown and distinguish a normalization problem from a coverage interaction. I could inspect the logs and code, but I could not execute this reproduction here. If the isolated test confirms the cycle traversal, the robust fix is explicit cycle detection before normalization. It should not depend on the interpreter eventually raising You are interacting with an AI system. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
ObservationIndeed when executed on Python 3.15, the process goes into an endless loop or infinite recursion, hogging one CPU core at 100%, impossible to be killed by a regular CTRL+C. The log output shows: .... with the main error location message RecapThe software test reads like this. def test_recursive_alias_raises_cleanly(tmp_path): """A self-recursive alias makes a cyclic structure that safe_load accepts but that cannot be flattened into a finite record; normalization hits Python's recursion limit and raises a bounded RecursionError rather than hanging or emitting corrupt data. Pathological input, pinned here as an unsupported-but-safe boundary (not a code-execution or data-leak hole).""" path = write_yaml(tmp_path / "cyclic.yaml", "a: &a [*a]\n") with pytest.raises(RecursionError): list(read_yaml(iter([FileItemStub(path)]), chunksize=10)) # ty: ignore[invalid-argument-type] Q&AIs that new behaviour intended? Any idea how to mitigate the problem? Should it be reported to the Python core team as a regression compared to Python 3.14? /cc @coderabbitai, @hampsterx |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash set -uo pipefail ast-grep outline tests/format/test_yaml.py rg -n -C 12 'def test_recursive_alias_raises_cleanly' tests/format/test_yaml.py ast-grep outline src/dlt_filesystem/source/format/iterable_codec.py rg -n -C 15 'map_nested_values_in_place|def _normalize_row|def read_yaml' src/dlt_filesystem/source/format/iterable_codec.py fd -t f '^(pyproject\.toml|uv\.lock)$' rg -n -C 4 'name = "dlt"|dlt[>=<~\[]|requires-python' pyproject.toml uv.lock Length of output: 11329 🤖 web_search executed:
Length of output: 16503 🏁 Script executed: #!/bin/bash set -uo pipefail for issue in 148260 131798; do echo "=== CPython issue $issue ===" gh api "repos/python/cpython/issues/$issue" --jq '{title,body,state,html_url}' done echo '=== dlt traversal implementation ===' curl -fsSL https://raw.githubusercontent.com/dlt-hub/dlt/devel/dlt/common/utils.py | python -c ' import sys s=sys.stdin.read().splitlines() for i,line in enumerate(s): if line.startswith("def map_nested_values_in_place("): end=next((j for j in range(i+1,len(s)) if s[j].startswith("def ")), min(i+140,len(s))) for j in range(max(0,i-2),end): print(f"{j+1}: {s[j]}") ' Length of output: 15406 🤖 web_search executed:
Length of output: 18707
What the traceback establishesThe hang occurs during recursive traversal in I inspected the upstream implementation. It recursively visits dictionaries, lists, and tuples without cycle detection. It does not catch The 100 repeated frames do not mean that recursion stopped at depth 100. Isolate the possible CPython regressionTry this standalone reproduction on both Python 3.14 and 3.15. It removes YAML, dlt, pytest, and coverage while preserving the relevant recursive call form: import faulthandler import sys def walk(value, *args, **kwargs): for index, child in enumerate(value): if isinstance(child, list): value[index] = walk(child, *args, **kwargs) return value print(sys.version, flush=True) print("recursion limit:", sys.getrecursionlimit(), flush=True) cycle = [] cycle.append(cycle) # Exit after dumping the stack, even if normal interruption fails. # exit=True skips cleanup; use this only in this diagnostic process. faulthandler.dump_traceback_later(10, exit=True) try: walk(cycle) except RecursionError: print("RecursionError raised as expected", flush=True) finally: faulthandler.cancel_dump_traceback_later() I have not executed this reproduction. If it hangs on 3.15 but raises
Disabling JIT is a diagnostic comparison, not a confirmed workaround. I did not find a verified matching CPython issue. Mitigation in this packageReject cycles explicitly before calling Use an iterative traversal with container identities on the active traversal path. Reject a container when its identity already occurs on that path. Do not reject every repeated identity: two fields can legitimately reference the same non-cyclic YAML anchor. For compatibility with the current test, the guard could raise an explicit This removes reliance on the interpreter eventually stopping cyclic traversal. Increasing the recursion limit would not fix the cycle. The test’s “unsupported-but-safe” description also needs qualification: this reproduction demonstrates an availability risk, although it does not demonstrate code execution or data disclosure. ✏️ Learnings added
You are interacting with an AI system. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@hampsterx: Is your clanker able to verify this on Python 3.14 vs. Python 3.15 and derive a corresponding outcome? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@amotl Confirmed locally on Linux x86_64 at
A dependency-free reproduction also confirms the difference: with the recursion limit set to 1,000, recursive calls forwarding This matches CPython #155151: the specialized I suggest retaining 3.14 in the matrix and rejecting cyclic input explicitly before enabling 3.15. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Excellent. Thanks for discovering the corresponding upstream ticket.
Thank you. Feel free to submit a relevant patch, optimally stacked on this one. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Use ty 0.0.91, matching main, when validating the stacked Python 3.15 patch.
Reject ancestor references in complete decoded values before splitting rows, so cyclic input cannot enter recursive normalization on Python 3.15. Retain finite aliases and cover cycles through CBOR tags and frozen mappings with timeout-bounded regressions. Keep Python 3.14 alongside 3.15 in CI.
Walk mapping keys as well as values because a CBOR tag can be its own frozen-mapping key. Pin that wire payload with a bounded reader regression.
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.