Skip to content

[Repo Assist] Fix Frame.ofRecords for internal/private record types#580

Merged
dsyme merged 7 commits intomasterfrom
repo-assist/fix-issue-562-nonpublic-records-1ae45186cfa8430a
Mar 9, 2026
Merged

[Repo Assist] Fix Frame.ofRecords for internal/private record types#580
dsyme merged 7 commits intomasterfrom
repo-assist/fix-issue-562-nonpublic-records-1ae45186cfa8430a

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Mar 8, 2026

🤖 This is an automated PR from Repo Assist.

Closes #562

Root Cause

Frame.ofRecords (and related record-expansion functions) uses reflection to discover properties and fields of record types. The search was limited to BindingFlags.Public, but F# compiles property accessors as assembly-visible (not strictly public) when the record type is marked internal. As a result, GetProperties(Public) returned nothing for internal records, silently producing an empty frame.

Fix

In src/Deedle/FrameUtils.fs, getExpandableProperties and getExpandableFields now include BindingFlags.NonPublic in the reflection search, with targeted filters to avoid including unwanted implementation-detail members:

  • Properties: Excludes explicit interface implementations (property names containing ., e.g. System.Runtime.CompilerServices.ITuple.Length) and private getters. Allows public or assembly-visible (internal) getters.
  • Fields: Excludes compiler-generated backing fields (those carrying CompilerGeneratedAttribute, e.g. F# record backing fields like Day@) and private fields.
  • p.GetGetMethod(nonPublic=true) is used to correctly retrieve non-public property getter methods.

Test Status

  • src/Deedle/Deedle.fsproj builds successfully (0 errors)
  • tests/Deedle.Tests/Deedle.Tests.fsproj builds successfully (0 errors)
  • ✅ New test Can read sequence of internal records added and verified manually
  • ✅ Existing regression tests verified (public records and tuples still produce correct columns)
  • ⚠️ .NET 5.0 is required to run the test suite via dotnet fake build, but the CI environment has only .NET 8/9/10. This is a pre-existing infrastructure constraint.

Trade-offs

This change makes Frame.ofRecords work with internal F# records defined in the same or another assembly. There is no change in behaviour for fully public types (the added filter excludes the same implementation-detail members that were previously invisible due to Public-only search).

Generated by Repo Assist for issue #562 ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@30f2254f2a7a944da1224df45d181a3f8faefd0d

Add BindingFlags.NonPublic to property and field searches in
getExpandableProperties and getExpandableFields so that F# records
marked as internal (or types with assembly-visible members) are
correctly expanded by Frame.ofRecords.

The fix also:
- Excludes explicit interface implementations (property names containing '.')
- Excludes compiler-generated backing fields (CompilerGeneratedAttribute)
- Excludes private members (only public or assembly-visible members included)
- Uses p.GetGetMethod(nonPublic=true) to retrieve non-public property getters

Co-authored-by: Copilot <[email protected]>
@dsyme dsyme marked this pull request as ready for review March 9, 2026 03:56
@dsyme dsyme merged commit c38feab into master Mar 9, 2026
2 checks passed
@dsyme dsyme deleted the repo-assist/fix-issue-562-nonpublic-records-1ae45186cfa8430a branch March 9, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Frame.ofRecords fails silently when underlaying record type is internal or private

1 participant