oarepo-runtime 2.0.0.dev33__py3-none-any.whl → 2.0.0.dev35__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,6 @@ from .api import Model
19
19
  from .ext import OARepoRuntime
20
20
  from .proxies import current_runtime
21
21
 
22
- __version__ = "2.0.0dev33"
22
+ __version__ = "2.0.0dev35"
23
23
 
24
24
  __all__ = ("Model", "OARepoRuntime", "__version__", "current_runtime")
oarepo_runtime/api.py CHANGED
@@ -310,10 +310,10 @@ class Model[
310
310
  @property
311
311
  def record_json_schema(self) -> str:
312
312
  """Get the json schema of the record."""
313
- schema: ConstantField[Record, str] | None = getattr(self.record_cls, "schema", None)
313
+ schema: ConstantField | None = getattr(self.record_cls, "schema", None)
314
314
  if schema is None:
315
315
  raise KeyError(f"Record class {self.record_cls} does not have a schema field.") # pragma: no cover
316
- return schema.value # type: ignore[no-any-return]
316
+ return cast("str", schema.value)
317
317
 
318
318
  @property
319
319
  def draft_pid_type(self) -> str | None:
@@ -256,7 +256,7 @@ class InfoResource(BaseResource):
256
256
  can_export: bool = True,
257
257
  can_deposit: bool = False,
258
258
  ) -> dict:
259
- schema_field = cast("ConstantField[Record, str] | None", getattr(record, "schema", None))
259
+ schema_field = cast("ConstantField | None", getattr(record, "schema", None))
260
260
  if schema_field is not None:
261
261
  schema_field_value = schema_field.value
262
262
  schema_path = base_url + schema_field_value.replace("local://", "")
@@ -10,7 +10,12 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ from .base import TypedSystemField
13
14
  from .mapping import MappingSystemFieldMixin
14
15
  from .publication_status import PublicationStatusSystemField
15
16
 
16
- __all__ = ("MappingSystemFieldMixin", "PublicationStatusSystemField")
17
+ __all__ = (
18
+ "MappingSystemFieldMixin",
19
+ "PublicationStatusSystemField",
20
+ "TypedSystemField",
21
+ )
@@ -0,0 +1,45 @@
1
+ #
2
+ # Copyright (c) 2025 CESNET z.s.p.o.
3
+ #
4
+ # This file is a part of oarepo-runtime (see https://github.com/oarepo/oarepo-runtime).
5
+ #
6
+ # oarepo-runtime is free software; you can redistribute it and/or modify it
7
+ # under the terms of the MIT License; see LICENSE file for more details.
8
+ #
9
+ """Base typed system field implementation."""
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Any, Self, overload
14
+
15
+ from invenio_records.api import Record
16
+ from invenio_records.extensions import ExtensionMixin
17
+ from invenio_records.systemfields import SystemField
18
+
19
+
20
+ class TypedSystemField[R: Record = Record, V: Any = Any](SystemField, ExtensionMixin):
21
+ """Base class for typed system fields."""
22
+
23
+ @overload
24
+ def __get__(self, instance: None, owner: type[R]) -> Self: ...
25
+
26
+ @overload
27
+ def __get__(self, instance: R, owner: type[R]) -> V: ...
28
+
29
+ def __get__(self, instance: R | None, owner: type[R]) -> Self | V: # type: ignore[override]
30
+ """Get the value of the field."""
31
+ if instance is None: # pragma: no cover
32
+ return self # pragma: no cover
33
+ raise NotImplementedError # pragma: no cover
34
+
35
+ @overload
36
+ def __set__(self, instance: None, value: Self) -> None: ...
37
+
38
+ @overload
39
+ def __set__(self, instance: R, value: V) -> None: ...
40
+
41
+ def __set__(self, instance: R | None, value: V | Self) -> None: # type: ignore[override]
42
+ """Set the value of the field."""
43
+ if instance is None: # pragma: no cover
44
+ raise ValueError("Cannot set value on class.") # pragma: no cover
45
+ raise NotImplementedError # pragma: no cover
@@ -10,17 +10,15 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- from typing import TYPE_CHECKING, override
13
+ from typing import TYPE_CHECKING
14
+
15
+ from invenio_records.api import Record
14
16
 
15
17
  if TYPE_CHECKING:
16
- from invenio_records.api import RecordBase
17
18
  from invenio_records.dumpers import Dumper
18
- from invenio_records.systemfields import SystemField
19
- else:
20
- SystemField = object
21
19
 
22
20
 
23
- class MappingSystemFieldMixin(SystemField):
21
+ class MappingSystemFieldMixin[R: Record = Record]:
24
22
  """Mixin class that provides default mapping, mapping settings, and dynamic templates for system fields."""
25
23
 
26
24
  @property
@@ -39,18 +37,14 @@ class MappingSystemFieldMixin(SystemField):
39
37
  return []
40
38
 
41
39
  # The following methods are added just for typing purposes.
42
- @override
43
- def pre_dump(self, record: RecordBase, data: dict, dumper: Dumper | None = None) -> None:
40
+ def pre_dump(self, record: R, data: dict, dumper: Dumper | None = None) -> None:
44
41
  """Dump record to the data - pre-dump phase."""
45
42
 
46
- @override
47
- def post_dump(self, record: RecordBase, data: dict, dumper: Dumper | None = None) -> None:
43
+ def post_dump(self, record: R, data: dict, dumper: Dumper | None = None) -> None:
48
44
  """Dump record to the data - post-dump phase."""
49
45
 
50
- @override
51
46
  def pre_load(self, data: dict, loader: Dumper | None = None) -> None:
52
47
  """Load record from the data - pre-load phase."""
53
48
 
54
- @override
55
- def post_load(self, record: RecordBase, data: dict, loader: Dumper | None = None) -> None:
49
+ def post_load(self, record: R, data: dict, loader: Dumper | None = None) -> None:
56
50
  """Load record from the data - post-load phase."""
@@ -10,18 +10,18 @@
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
- from typing import TYPE_CHECKING, Any, override
13
+ from typing import TYPE_CHECKING, Self, override
14
14
 
15
- from invenio_records.systemfields import SystemField
15
+ from invenio_records.api import Record
16
16
 
17
+ from .base import TypedSystemField
17
18
  from .mapping import MappingSystemFieldMixin
18
19
 
19
20
  if TYPE_CHECKING:
20
- from invenio_records.api import RecordBase
21
21
  from invenio_records.dumpers import Dumper
22
22
 
23
23
 
24
- class PublicationStatusSystemField(MappingSystemFieldMixin, SystemField):
24
+ class PublicationStatusSystemField(MappingSystemFieldMixin, TypedSystemField[Record, str]):
25
25
  """A system field to track the status of a record (either 'draft' or 'published').
26
26
 
27
27
  The default key for this field is 'publication_status', but it can be customized.
@@ -41,21 +41,20 @@ class PublicationStatusSystemField(MappingSystemFieldMixin, SystemField):
41
41
  }
42
42
 
43
43
  @override
44
- def post_load(self, record: RecordBase, data: dict, loader: Dumper | None = None) -> None:
44
+ def post_load(self, record: Record, data: dict, loader: Dumper | None = None) -> None:
45
45
  data.pop(self.key, None)
46
46
 
47
47
  @override
48
- def post_dump(self, record: RecordBase, data: dict, dumper: Dumper | None = None) -> None:
49
- if self.key is None:
50
- return # pragma: no cover
48
+ def post_dump(self, record: Record, data: dict, dumper: Dumper | None = None) -> None:
51
49
  if not self.attr_name:
52
50
  raise ValueError( # pragma: no cover
53
51
  "attr_name must be set for PublicationStatusSystemField"
54
52
  )
55
53
  data[self.key] = getattr(record, self.attr_name)
56
54
 
57
- def __get__(self, record: RecordBase | None, owner: Any = None) -> Any:
55
+ @override
56
+ def __get__(self, instance: Record | None, owner: type[Record]) -> Self | str: # type: ignore[override]
58
57
  """Access the attribute."""
59
- if record is None:
58
+ if instance is None:
60
59
  return self
61
- return "draft" if getattr(record, "is_draft", False) else "published"
60
+ return "draft" if getattr(instance, "is_draft", False) else "published"
@@ -1,15 +1,15 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oarepo-runtime
3
- Version: 2.0.0.dev33
3
+ Version: 2.0.0.dev35
4
4
  Summary: A set of runtime extensions of Invenio repository
5
5
  Project-URL: Homepage, https://github.com/oarepo/oarepo-runtime
6
6
  License-Expression: MIT
7
7
  License-File: LICENSE
8
8
  Requires-Python: <3.14,>=3.13
9
9
  Requires-Dist: langcodes>=3.5.0
10
+ Requires-Dist: oarepo-invenio-typing-stubs>=0.1.0
10
11
  Requires-Dist: oarepo[rdm,tests]<15,>=13
11
12
  Provides-Extra: dev
12
- Requires-Dist: oarepo-invenio-typing-stubs>=0.1.0; extra == 'dev'
13
13
  Requires-Dist: pytest>=7.1.2; extra == 'dev'
14
14
  Provides-Extra: oarepo13
15
15
  Requires-Dist: oarepo[rdm]<14,>=13; extra == 'oarepo13'
@@ -1,5 +1,5 @@
1
- oarepo_runtime/__init__.py,sha256=Yyknq93rocqlDSiPoWRbMXKm60R9oaLNgvJ3nO3ABMY,686
2
- oarepo_runtime/api.py,sha256=tLPgKv1iao2ZeL0tTJeA85019_sMW_dQAleayOeXjgI,14200
1
+ oarepo_runtime/__init__.py,sha256=VGinT5vziEg9nmT32QIwedHQ1YgRBlV5EXie4fjixkM,686
2
+ oarepo_runtime/api.py,sha256=6AHyFnf0Cg1nfhGaQFMPjynVvrp1UURo8vX5vb5LvC4,14169
3
3
  oarepo_runtime/config.py,sha256=RUEPFn_5bKp9Wb0OY-Fb3VK30m35vF5IsLjYaQHhP3g,3838
4
4
  oarepo_runtime/ext.py,sha256=NgiRNl_hwTvEWcXnNwVh_XCPJyvwr3dZkdPmkWvN1xo,8785
5
5
  oarepo_runtime/proxies.py,sha256=x8Y1iTP8QIzSI67s90VR0_5fvXuT1xlJXtAHsaoXFwg,903
@@ -8,15 +8,16 @@ oarepo_runtime/typing.py,sha256=vH8UUb4QTJowuvibwHaOOEwxx8i21LcOeplxJl0Yrew,1594
8
8
  oarepo_runtime/cli/__init__.py,sha256=H7GOeOBf0udgKWOdlAQswIMvRrD8BwcEjOVxIqP0Suw,731
9
9
  oarepo_runtime/cli/search.py,sha256=4fHkrjltUUPVUzJiuWaiWxTk62rIYxal3_3jRsZVMmI,1175
10
10
  oarepo_runtime/info/__init__.py,sha256=qRG3mSyoiw7sKm9StiuBJs6l15HrdAQ4sphsAQsJtQc,336
11
- oarepo_runtime/info/views.py,sha256=-ZBKkJgzaaYDU5cS7DuG5Cem4M42ohQ-LN6BaCXjo1I,16967
11
+ oarepo_runtime/info/views.py,sha256=JwESs-KVq163OBeqWVwfy0RU4WXR_MBolVR7W-dGtm0,16954
12
12
  oarepo_runtime/records/__init__.py,sha256=AbWzmVCY7MhrpdEeI0e3lKzeugPMUSo8T08-NBVeig4,339
13
13
  oarepo_runtime/records/drafts.py,sha256=b45ROjd9lwy6ratrpAruimcKvQmJradk5JgILoBAHmY,1965
14
14
  oarepo_runtime/records/mapping.py,sha256=fn6M208axxBqHtRV6qKQukwUw1z0hq_KF4qfuB2rr98,2630
15
15
  oarepo_runtime/records/pid_providers.py,sha256=DE8uW-QmJumA9OqWksDOydezjJ9LLC296CRa0zDrlEc,1747
16
- oarepo_runtime/records/systemfields/__init__.py,sha256=g-u408qyNnsbUTpDtVVwlcyiJaO68GTjDN0W9rXs9pk,524
16
+ oarepo_runtime/records/systemfields/__init__.py,sha256=tJzOOQ8dBlCyD8tCAriIUZggZ73UjMyMOp6IlSV-Tb4,594
17
+ oarepo_runtime/records/systemfields/base.py,sha256=EWSdVsWePkdwksRQ9yaMMk9Mrhicw-ZE0vdApn2EjWQ,1602
17
18
  oarepo_runtime/records/systemfields/custom_fields.py,sha256=PEoaCEnvanysFQAaqTtD9-VwaBmnFkoP2pmpCl9ZFfI,2237
18
- oarepo_runtime/records/systemfields/mapping.py,sha256=HC9QnY6J6Ftw-DwotKUTvnyRif7XHhMKdZfSTDJJqSk,1880
19
- oarepo_runtime/records/systemfields/publication_status.py,sha256=1g3VXNPh0FsiPCpe-7ZuaMEF4x8ffrDrt37Rqnjp0ng,2027
19
+ oarepo_runtime/records/systemfields/mapping.py,sha256=GcNp_-Ho3G8nk4-SXgoWWk_IPdGsM0LZ-DBl5fnYJvE,1699
20
+ oarepo_runtime/records/systemfields/publication_status.py,sha256=5D8L_-Wsf-Or-Er7EhuOnwzXfGY28TRPTg1XmMEKxM8,1995
20
21
  oarepo_runtime/records/systemfields/selectors.py,sha256=ijVDwAXaXTV5NtcXsrALkhddgCogLNe2eEscFr23qyg,1656
21
22
  oarepo_runtime/resources/__init__.py,sha256=voynQULXoOEviADkbOpekMphZPTAz4IOTg5BF9xPwTM,453
22
23
  oarepo_runtime/resources/config.py,sha256=Lbx1QPWAJ8z1truhYntbnhGGWp2OCcwqKm6BuvPJNT0,1330
@@ -41,8 +42,8 @@ oarepo_runtime/services/schema/__init__.py,sha256=jgAPI_uKC6Ug4KQWnwQVg3-aNaw-eH
41
42
  oarepo_runtime/services/schema/i18n.py,sha256=9D1zOQaPKAnYzejB0vO-m2BJYnam0N0Lrq4jID7twfE,3174
42
43
  oarepo_runtime/services/schema/i18n_ui.py,sha256=DbusphhGDeaobTt4nuwNgKZ6Houlu4Sv3SuMGkdjRRY,3582
43
44
  oarepo_runtime/services/schema/ui.py,sha256=Y_jBO-fowkpOgceWz8aqJSJAUiAnKLGSIuNpjNLnp8Q,4612
44
- oarepo_runtime-2.0.0.dev33.dist-info/METADATA,sha256=I1Ojqa6TlUdZEkdhaG4i8CqqzQzvU_ZemZoPGFLLmfk,4723
45
- oarepo_runtime-2.0.0.dev33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
46
- oarepo_runtime-2.0.0.dev33.dist-info/entry_points.txt,sha256=rOfs8R1oXFN_dLH9zAZ6ydkvr83mDajegc6NBIRsCMQ,318
47
- oarepo_runtime-2.0.0.dev33.dist-info/licenses/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
48
- oarepo_runtime-2.0.0.dev33.dist-info/RECORD,,
45
+ oarepo_runtime-2.0.0.dev35.dist-info/METADATA,sha256=xI4aL-6OK_IN3C5QVz-uXcuKH48Tw9h80-ZvJOFUoFI,4707
46
+ oarepo_runtime-2.0.0.dev35.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
47
+ oarepo_runtime-2.0.0.dev35.dist-info/entry_points.txt,sha256=rOfs8R1oXFN_dLH9zAZ6ydkvr83mDajegc6NBIRsCMQ,318
48
+ oarepo_runtime-2.0.0.dev35.dist-info/licenses/LICENSE,sha256=h2uWz0OaB3EN-J1ImdGJZzc7yvfQjvHVYdUhQ-H7ypY,1064
49
+ oarepo_runtime-2.0.0.dev35.dist-info/RECORD,,