Skip to content

Commit

Permalink
Merge pull request #84 from axelboc/fix-datatype
Browse files Browse the repository at this point in the history
Fix calling `get_attribute_names` on committed datatype
  • Loading branch information
bmaranville authored Sep 5, 2024
2 parents a7bc6b4 + 327f6c7 commit b5f5b71
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 39 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog
## v0.7.8 TBC
### Fixed
- Fix accessing attributes of committed datatype with `my_datafile.attrs`.
- Fix calling `get_attribute_names` method of Module API on committed datatype.
### Changed
- Mark optional parameters as such in the TypeScript declarations of the following `H5Module` methods: `open`, `create_dataset`, `create_group`, `create_vlen_str_dataset` and `get_keys_vector`.
## v0.7.7 2024-08-28
Expand Down
27 changes: 12 additions & 15 deletions src/hdf5_hl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ declare enum OBJECT_TYPE {
REFERENCE = "Reference",
REGION_REFERENCE = "RegionReference"
}
export declare type Entity = Dataset | Group | BrokenSoftLink | ExternalLink | Datatype | Reference | RegionReference;
export declare class BrokenSoftLink {
target: string;
type: OBJECT_TYPE;
Expand All @@ -50,13 +51,6 @@ export declare class ExternalLink {
type: OBJECT_TYPE;
constructor(filename: string, obj_path: string);
}
export declare class Datatype {
file_id: bigint;
path: string;
type: OBJECT_TYPE;
constructor(file_id: bigint, path: string);
get metadata(): Metadata;
}
export declare class Reference {
ref_data: Uint8Array;
constructor(ref_data: Uint8Array);
Expand All @@ -81,30 +75,33 @@ declare abstract class HasAttrs {
file_id: bigint;
path: string;
type: OBJECT_TYPE;
get attrs(): {
[key: string]: Attribute;
};
get attrs(): Record<string, Attribute>;
get root(): Group;
get parent(): Group;
get_attribute(name: string, json_compatible: true): JSONCompatibleOutputData;
get_attribute(name: string, json_compatible: false): OutputData;
create_attribute(name: string, data: GuessableDataTypes, shape?: number[] | null, dtype?: string | null): void;
delete_attribute(name: string): number;
create_reference(): Reference;
dereference(ref: Reference | RegionReference): BrokenSoftLink | ExternalLink | Datatype | Group | Dataset | DatasetRegion | null;
dereference(ref: RegionReference): DatasetRegion;
dereference(ref: Reference | RegionReference): DatasetRegion | Entity | null;
}
export declare class Datatype extends HasAttrs {
constructor(file_id: bigint, path: string);
get metadata(): Metadata;
}
export declare class Group extends HasAttrs {
constructor(file_id: bigint, path: string);
keys(): Array<string>;
values(): Generator<BrokenSoftLink | ExternalLink | Datatype | Group | Dataset | null, void, unknown>;
items(): Generator<(string | BrokenSoftLink | ExternalLink | Datatype | Group | Dataset | null)[], void, unknown>;
keys(): string[];
values(): Generator<Entity | null, void, never>;
items(): Generator<[string, Entity | null], void, never>;
get_type(obj_path: string): number;
get_link(obj_path: string): string;
get_external_link(obj_path: string): {
filename: string;
obj_path: string;
};
get(obj_name: string): BrokenSoftLink | ExternalLink | Datatype | Group | Dataset | null;
get(obj_name: string): Entity | null;
create_group(name: string, track_order?: boolean): Group;
create_dataset(args: {
name: string;
Expand Down
50 changes: 26 additions & 24 deletions src/hdf5_hl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,8 @@ enum OBJECT_TYPE {
REGION_REFERENCE = 'RegionReference',
}

export type Entity = Dataset | Group | BrokenSoftLink | ExternalLink | Datatype | Reference | RegionReference;

export class BrokenSoftLink {
// only used for broken links...
target: string;
Expand All @@ -523,20 +525,6 @@ export class ExternalLink {
}
}

export class Datatype {
file_id: bigint;
path: string;
type: OBJECT_TYPE = OBJECT_TYPE.DATATYPE
constructor(file_id: bigint, path: string) {
this.file_id = file_id;
this.path = path;
}

get metadata() {
return Module.get_datatype_metadata(this.file_id, this.path);
}
}

export class Reference {
ref_data: Uint8Array;
constructor(ref_data: Uint8Array) {
Expand Down Expand Up @@ -598,7 +586,7 @@ abstract class HasAttrs {

get attrs() {
let attr_names = Module.get_attribute_names(this.file_id, this.path) as string[];
let attrs: {[key: string]: Attribute} = {};
let attrs: Record<string, Attribute> = {};
const { file_id, path } = this;
for (let name of attr_names) {
Object.defineProperty(attrs, name, {
Expand All @@ -607,7 +595,6 @@ abstract class HasAttrs {
});
}
return attrs;

}

get root() {
Expand Down Expand Up @@ -677,14 +664,29 @@ abstract class HasAttrs {
return new Reference(ref_data);
}

dereference(ref: Reference | RegionReference) {
dereference(ref: RegionReference): DatasetRegion;
dereference(ref: Reference | RegionReference): DatasetRegion | Entity | null;
dereference(ref: Reference | RegionReference): DatasetRegion | Entity | null {
const is_region = (ref instanceof RegionReference);
const name = Module.get_referenced_name(this.file_id, ref.ref_data, !is_region);
const target = this.root.get(name);
return (is_region) ? new DatasetRegion(target as Dataset, ref) : target;
}
}

export class Datatype extends HasAttrs {
constructor(file_id: bigint, path: string) {
super();
this.file_id = file_id;
this.path = path;
this.type = OBJECT_TYPE.DATATYPE;
}

get metadata() {
return Module.get_datatype_metadata(this.file_id, this.path);
}
}

export class Group extends HasAttrs {
constructor(file_id: bigint, path: string) {
super();
Expand All @@ -693,22 +695,22 @@ export class Group extends HasAttrs {
this.type = OBJECT_TYPE.GROUP;
}

keys(): Array<string> {
return Module.get_names(this.file_id, this.path, false) as string[];
keys(): string[] {
return Module.get_names(this.file_id, this.path, false);
}

* values() {
* values(): Generator<Entity | null, void, never> {
for (let name of this.keys()) {
yield this.get(name);
}
return
return;
}

* items() {
* items(): Generator<[string, Entity | null], void, never> {
for (let name of this.keys()) {
yield [name, this.get(name)];
}
return
return;
}

get_type(obj_path: string) {
Expand All @@ -723,7 +725,7 @@ export class Group extends HasAttrs {
return Module.get_external_link(this.file_id, obj_path);
}

get(obj_name: string) {
get(obj_name: string): Entity | null {
let fullpath = (/^\//.test(obj_name)) ? obj_name : this.path + "/" + obj_name;
fullpath = normalizePath(fullpath);

Expand Down
4 changes: 4 additions & 0 deletions src/hdf5_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ val get_attribute_names(hid_t loc_id, const std::string& obj_name_string)
{
ocpl_id = H5Gget_create_plist(obj_id);
}
else if (obj_type == H5O_TYPE_NAMED_DATATYPE)
{
ocpl_id = H5Tget_create_plist(obj_id);
}
else
{
ocpl_id = H5Dget_create_plist(obj_id);
Expand Down
Binary file modified test/array.h5
Binary file not shown.
Binary file modified test/compressed.h5
Binary file not shown.
4 changes: 4 additions & 0 deletions test/datatype_test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ async function datatype_test() {
littleEndian: false,
size: 10
});

assert.deepEqual(Object.keys(datatype.attrs), ['named_dtype_attr']);
assert.deepEqual(datatype.attrs['named_dtype_attr'].value,
'An attribute of a named datatype');
}

export const tests = [
Expand Down
1 change: 1 addition & 0 deletions test/make_test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
f.create_dataset("bool", data=[[False, True], [True, False]], shape=(2,2))
f.create_dataset("bigint", data=np.arange(8).reshape(2,2,2), dtype="<i8", shape=(2,2,2))
f["datatype/value"] = np.dtype("S10")
f["datatype/value"].attrs["named_dtype_attr"] = "An attribute of a named datatype"

f.create_dataset("bigendian", data=[3,2,1], dtype='>f4')
f['bigendian'].attrs.create("bigendian_attr", [3,2,1], dtype='>i8')
Expand Down

0 comments on commit b5f5b71

Please sign in to comment.