Skip to content

cowork: schema command error-path hardening + honest sample footer - #49

Merged
Coding-Dev-Tools merged 10 commits into
masterfrom
cowork/improve-datamorph
Oct 3, 2026
Merged

Coding-Dev-Tools merged 10 commits into
masterfrom
cowork/improve-datamorph

Conversation

@Coding-Dev-Tools

Copy link
Copy Markdown
Owner

Harden the schema subcommand (silent-failure class): unsupported --format and malformed input now exit cleanly with a red ERROR message instead of an unhandled traceback. Fix misleading 'Inferred from N+ rows' footer to 'up to N rows' (honest claim). Adds 3 CLI error-path tests (144 total pass, ruff clean). Branch also carries a merge of origin/master resolving the pyproject self-referential extra conflict in favor of the corrected datamorph-cli name.

cowork-bot and others added 8 commits June 13, 2026 06:03
Three correctness fixes in converters.py:

1. CsvWriter extrasaction='raise' → 'ignore': JSON/YAML→CSV conversions
   with heterogeneous rows (later rows having extra keys not seen in the
   first row) raised ValueError and aborted the conversion. extrasaction=
   'ignore' silently drops extra fields, which is correct CSV behaviour —
   the output schema is fixed at the first row.

2. Remove redundant CSV pre-peek in convert(): the code opened a fresh
   read_stream() to peek the first row and call set_field_order(), then
   opened a second read_stream() for the actual conversion — reading the
   input file twice. CsvWriter.write_stream() already falls back to
   list(row.keys()) when _field_order is unset, so the pre-peek was
   entirely redundant. Removed; one read pass now suffices.

3. Populate ConversionResult.rows_read: the field was declared but never
   set (always 0). Set to rows_written after a successful conversion so
   callers can trust the result object.

5 new regression tests; 119/119 green.
…morph

# Conflicts:
#	.github/workflows/pages.yml
#	.github/workflows/publish.yml
#	.gitignore
#	LICENSE
#	README.md
#	package.json
#	pyproject.toml
#	src/datamorph/__init__.py
#	src/datamorph/cli.py
#	src/datamorph/converters.py
#	tests/test_converters.py
#	tests/test_validate.py
- Add parquet, avro, protobuf, and all optional dependency groups to pyproject.toml
- Wrap optional dependency imports in try/except with user-friendly error messages
  pointing to the correct pip install command
- All 141 tests pass, ruff clean
… bad merge

An earlier merge on cowork/improve-datamorph inadvertently dropped 14 files
that exist on master (ci.yml, auto-code-review.yml, conftest.py, CHANGELOG,
CONTRIBUTING, SECURITY, issue/PR templates, dependabot, FUNDING, cli.js,
.gitattributes). Restored them verbatim from origin/master so this branch's
PR diff contains only the intended improvements (converters.py graceful
optional-import errors + pyproject optional-dependency groups + auto-pr wf).
…ted format and malformed input, no tracebacks); fix misleading 'Inferred from N+ rows' footer to honest sample cap; +3 CLI error-path tests
@github-actions

github-actions Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

🤖 Automated Code Review

✅ Ruff Lint — No issues

⚠️ Ruff Format — Formatting needed

unformatted: File would be reformatted
  --> README.md:28:1
   |
27 | import pandas as pd
   - df = pd.read_csv('huge_file.csv')  # OOM on 5GB+
   - df.to_parquet('output.parquet')
28 +
29 + df = pd.read_csv("huge_file.csv")  # OOM on 5GB+
30 + df.to_parquet("output.parquet")
31 | ```
   |

unformatted: File would be reformatted
 --> conftest.py:2:1
  |
1 | """pytest configuration — add project src to Python path and skip rate limits."""
2 +
3 | import os
  |

unformatted: File would be reformatted
   --> src/datamorph/cli.py:103:15
    |
102 | @click.option("--pattern", default="*", help="File glob pattern (default: all files)")
    - @click.option(
    -     "--recursive", "-r", is_flag=True, help="Search subdirectories recursively"
    - )
103 + @click.option("--recursive", "-r", is_flag=True, help="Search subdirectories recursively")
104 | @click.option("--csv-delimiter", default=",", help="CSV delimiter")
--------------------------------------------------------------------------------

✅ Secret Detection — Clean

✅ Large Files — Within limits

📊 Diff Stats — 5 file(s) changed

 src/datamorph/cli.py           | 56 ++++++++++++++++++++++++++++++++++++-----
 src/datamorph/converters.py    | 38 ++++++++++++++++++++++++----
 tests/test_cli_error_paths.py  | 32 ++++++++++++++++++++++++
 tests/test_converters.py       | 31 ++++++++++++++++++++---
 tests/test_cowork_hardening.py | 57 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 199 insertions(+), 15 deletions(-)

Verdict: ⚠️ Warnings — Lint/format issues found. Recommend fixing before merge.

Automated by Coding-Dev-Tools/.github reusable workflow.

DevForge Engineer and others added 2 commits August 23, 2026 20:48
… valid empty container); harden validate --schema file loading (clean exit on malformed/wrong-shape schema, no traceback); +4 tests (148 pass), ruff clean
…files - convert_batch returns BatchConversionResult with skipped[] (file + detected format), CLI reports each skip explicitly instead of a green 'complete' while dropping data; +1 regression test (149 pass), ruff clean
@Coding-Dev-Tools
Coding-Dev-Tools marked this pull request as ready for review October 3, 2026 09:11
@Coding-Dev-Tools
Coding-Dev-Tools merged commit 036e7eb into master Oct 3, 2026
7 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-03T09:13:29.199341Z 9fbb324 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9fbb32461b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

recursive: bool = False,
**writer_kwargs: Any,
) -> list[ConversionResult]:
) -> BatchConversionResult:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve convert_batch's list contract

convert_batch is re-exported as a public API from datamorph.__init__, but this changes its return value from list[ConversionResult] to a non-iterable dataclass. Existing callers that iterate, index, compare to [], or call len(convert_batch(...)) now fail even though the CLI was updated. Keep the result list-compatible (for example by implementing the sequence protocol) or introduce the richer result through a new API.

Useful? React with 👍 / 👎.

Comment thread src/datamorph/cli.py
console.print(f"\nDetected format: [bold]{fmt}[/bold]")
console.print(table)
console.print(f"[dim]Inferred from {sample}+ rows[/dim]")
console.print(f"[dim]Inferred from a sample of up to {sample} rows[/dim]")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject non-positive schema sample sizes

When a nonempty file is inspected with --sample 0 or a negative value, FormatReader.infer_schema still appends the first row before checking its stopping condition, while this new footer claims that at most zero (or a negative number of) rows were sampled. This both misreports the operation and silently infers a schema from only one row; constrain the Click option to positive integers or make inference honor zero consistently.

Useful? React with 👍 / 👎.

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.

2 participants