Repository navigation
FileContext.type_by_name returns object: a lookup can be an annotated builtin #147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sathabbott
merged 5 commits into
nsmith-:main
from
sathabbott:fix/135-type-by-name-object
Oct 5, 2026
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
daa551c
FileContext.type_by_name returns object: a lookup can be an annotated…
sathabbott d600428
Merge remote-tracking branch 'upstream/main' into fix/135-type-by-nam…
sathabbott cd63cf8
tests: drop the object annotations #145 added for string records
sathabbott eb0b722
Merge remote-tracking branch 'upstream/main' into fix/135-type-by-nam…
sathabbott db3e332
Say what Locator's type variable is for
sathabbott File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| from pathlib import Path | ||
| from typing import get_type_hints | ||
|
|
||
| import pytest | ||
|
|
||
| from rootfilespec.bootstrap import BOOTSTRAP_CONTEXT, TNamed, TString | ||
| from rootfilespec.bootstrap.strings import TStringLong | ||
| from rootfilespec.bootstrap.TDatime import TDatime | ||
| from rootfilespec.bootstrap.TKey import TKey | ||
| from rootfilespec.dynamic import DynamicFileContext | ||
| from rootfilespec.reader import open_path | ||
| from rootfilespec.serializable import FileContext, ROOTSerializable, read_value | ||
|
|
||
| DATA = Path(__file__).parent.parent / "reference" / "root-io-spec" / "data" | ||
| UNFRAMED = DATA / "serialization" / "unframed-records.root" | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "method", | ||
| [ | ||
| FileContext.type_by_name, | ||
| type(BOOTSTRAP_CONTEXT).type_by_name, | ||
| DynamicFileContext.type_by_name, | ||
| TKey.read_from, | ||
| ], | ||
| ) | ||
| def test_return_type_is_object(method): | ||
| """Issue #135: a lookup can return an annotated builtin, not only a class, | ||
| and a key can read as a builtin, so neither is typed as ROOTSerializable""" | ||
| assert get_type_hints(method)["return"] is object | ||
|
|
||
|
|
||
| @pytest.mark.skipif(not UNFRAMED.exists(), reason="root-io-spec not checked out") | ||
| def test_lookup_of_tdatime_is_an_annotated_builtin(): | ||
| """root-io-spec serialization/unframed-records stores a TDatime as a record | ||
| of its own; its class name resolves to the annotated alias, which read_value | ||
| reads and which has no read method. The case.toml pins the payload at 318: | ||
| 0x7E6CC000, 2026-09-22 12:00:00 packed""" | ||
| with open_path(UNFRAMED) as reader: | ||
| (key,) = [k for k in reader.keylist().values() if k.fClassName == b"TDatime"] | ||
| buffer = reader.fetch.buffer(key) | ||
| readtype = buffer.file_context.type_by_name("TDatime") | ||
| assert readtype is TDatime | ||
| assert not isinstance(readtype, type) | ||
| payload = buffer[key.header.fKeylen :] | ||
| value, rest = read_value(readtype, payload) | ||
| assert value == 0x7E6CC000 | ||
| assert not rest | ||
| # mypy rejects this call, which is what #135 asks for | ||
| with pytest.raises(AttributeError): | ||
| readtype.read(payload) # type: ignore[attr-defined] | ||
| assert reader.fetch(key) == 0x7E6CC000 | ||
|
|
||
|
|
||
| @pytest.mark.skipif(not UNFRAMED.exists(), reason="root-io-spec not checked out") | ||
| @pytest.mark.parametrize( | ||
| ("name", "expected"), | ||
| [("TString", TString), ("TStringLong", TStringLong), ("string", TString)], | ||
| ) | ||
| def test_lookup_of_strings(name: str, expected: object): | ||
| """The string classes resolve to their annotated aliases (#68), in the | ||
| bootstrap context and in a file's""" | ||
| with open_path(UNFRAMED) as reader: | ||
| key = next(iter(reader.keylist().values())) | ||
| context = reader.fetch.buffer(key).file_context | ||
| for ctx in (BOOTSTRAP_CONTEXT, context): | ||
| assert ctx.type_by_name(name) is expected | ||
|
|
||
|
|
||
| def test_lookup_of_a_class_narrows(): | ||
| """A caller that needs the class narrows the result""" | ||
| readtype = BOOTSTRAP_CONTEXT.type_by_name("TNamed") | ||
| assert isinstance(readtype, type) | ||
| assert issubclass(readtype, ROOTSerializable) | ||
| assert readtype is TNamed |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.