sdmxlib 0.67.0__tar.gz → 0.68.0__tar.gz

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.
Files changed (178) hide show
  1. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/PKG-INFO +5 -4
  2. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/pyproject.toml +16 -12
  3. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/pyproject.toml.orig +40 -13
  4. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/__init__.py +95 -11
  5. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/_time.py +28 -0
  6. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/client.py +26 -9
  7. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/federated.py +28 -24
  8. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/query.py +6 -6
  9. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/registry.py +150 -76
  10. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/session.py +14 -6
  11. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/builders/contentconstraint.py +27 -10
  12. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/__init__.py +118 -49
  13. sdmxlib-0.68.0/src/sdmxlib/formats/_attachment.py +59 -0
  14. sdmxlib-0.68.0/src/sdmxlib/formats/_positions.py +55 -0
  15. sdmxlib-0.68.0/src/sdmxlib/formats/_refuse.py +164 -0
  16. sdmxlib-0.68.0/src/sdmxlib/formats/gaps.py +1592 -0
  17. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_csv/reader.py +12 -12
  18. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/_data_common.py +34 -12
  19. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/_dto.py +82 -12
  20. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json/_header.py +155 -0
  21. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json/_losses.py +298 -0
  22. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json/_periods.py +88 -0
  23. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/_resolve.py +15 -16
  24. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/_structure_dto.py +1007 -107
  25. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json/_structure_ingest.py +1603 -0
  26. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/data_v1.py +13 -6
  27. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/data_v2.py +17 -10
  28. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/metadata.py +26 -11
  29. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json/reader.py +773 -0
  30. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/structure_values.py +19 -5
  31. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/writer.py +103 -22
  32. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_json_1_0/writer.py +301 -0
  33. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_allowed_children.py +4191 -0
  34. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_closed_world.py +270 -0
  35. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_common.py +2463 -0
  36. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_header.py +262 -0
  37. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_losses.py +422 -0
  38. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml/_v3_reader.py +1351 -0
  39. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml/_v3_writer.py +488 -121
  40. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml21/_providers.py +159 -0
  41. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml21/_synthetic.py +58 -0
  42. sdmxlib-0.68.0/src/sdmxlib/formats/sdmx_ml21/reader.py +1613 -0
  43. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml21/writer.py +491 -131
  44. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml30/metadata.py +62 -34
  45. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml30/reader.py +1 -1
  46. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml30/writer.py +5 -0
  47. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml31/reader.py +1 -1
  48. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml31/writer.py +5 -0
  49. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/local/registry.py +385 -273
  50. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/__init__.py +75 -13
  51. sdmxlib-0.68.0/src/sdmxlib/model/_binding.py +47 -0
  52. sdmxlib-0.68.0/src/sdmxlib/model/_container.py +47 -0
  53. sdmxlib-0.68.0/src/sdmxlib/model/_invariants.py +114 -0
  54. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/_items.py +55 -54
  55. sdmxlib-0.68.0/src/sdmxlib/model/_rebind.py +92 -0
  56. sdmxlib-0.68.0/src/sdmxlib/model/_referenceable.py +354 -0
  57. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/_refshape.py +62 -5
  58. sdmxlib-0.68.0/src/sdmxlib/model/_resolvers.py +56 -0
  59. sdmxlib-0.68.0/src/sdmxlib/model/_rules.py +286 -0
  60. sdmxlib-0.68.0/src/sdmxlib/model/_tree.py +385 -0
  61. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/annotations.py +44 -7
  62. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/base.py +89 -23
  63. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/binding.py +8 -8
  64. sdmxlib-0.68.0/src/sdmxlib/model/category.py +178 -0
  65. sdmxlib-0.68.0/src/sdmxlib/model/codelist.py +1020 -0
  66. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/collections.py +11 -2
  67. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/concept.py +69 -20
  68. sdmxlib-0.68.0/src/sdmxlib/model/constraint.py +670 -0
  69. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/convert.py +34 -6
  70. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/dataflow.py +26 -13
  71. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/dataset.py +15 -13
  72. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/datastructure.py +316 -151
  73. sdmxlib-0.68.0/src/sdmxlib/model/errors.py +219 -0
  74. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/expr.py +13 -5
  75. sdmxlib-0.68.0/src/sdmxlib/model/header.py +133 -0
  76. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/hierarchy.py +132 -244
  77. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/in_memory_registry.py +128 -165
  78. sdmxlib-0.68.0/src/sdmxlib/model/link.py +61 -0
  79. sdmxlib-0.68.0/src/sdmxlib/model/mapping.py +761 -0
  80. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/message.py +128 -5
  81. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/metadata_provision.py +23 -13
  82. sdmxlib-0.68.0/src/sdmxlib/model/metadataflow.py +186 -0
  83. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/metadataset.py +35 -18
  84. sdmxlib-0.68.0/src/sdmxlib/model/metadatastructure.py +330 -0
  85. sdmxlib-0.68.0/src/sdmxlib/model/organisation.py +656 -0
  86. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/provision.py +25 -12
  87. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/ref.py +88 -46
  88. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/registry.py +7 -3
  89. sdmxlib-0.68.0/src/sdmxlib/model/representation.py +190 -0
  90. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/rollup.py +22 -19
  91. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/urn.py +7 -6
  92. sdmxlib-0.68.0/src/sdmxlib/model/validation.py +3447 -0
  93. sdmxlib-0.68.0/src/sdmxlib/model/valuelist.py +88 -0
  94. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/version.py +112 -33
  95. sdmxlib-0.68.0/src/sdmxlib/model/version_rewrite.py +276 -0
  96. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/polars.py +6 -6
  97. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_common.py +3 -1
  98. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_compile.py +39 -14
  99. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_edges.py +103 -77
  100. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_execute.py +4 -0
  101. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_expr.py +18 -4
  102. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/accessors.py +451 -261
  103. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/query.py +5 -2
  104. sdmxlib-0.68.0/src/sdmxlib/storage/_checked.py +42 -0
  105. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/_kinds.py +13 -1
  106. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/lazy.py +301 -182
  107. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/readers.py +1254 -414
  108. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/resolve.py +353 -50
  109. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/schema.py +669 -51
  110. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/writers.py +943 -285
  111. sdmxlib-0.68.0/src/sdmxlib/versions.py +15 -0
  112. sdmxlib-0.67.0/src/sdmxlib/formats/gaps.py +0 -688
  113. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_json/_structure_ingest.py +0 -936
  114. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_json/reader.py +0 -394
  115. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_json_1_0/writer.py +0 -194
  116. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_ml/_common.py +0 -1484
  117. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_ml/_v3_reader.py +0 -1195
  118. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_ml21/_synthetic.py +0 -25
  119. sdmxlib-0.67.0/src/sdmxlib/formats/sdmx_ml21/reader.py +0 -1182
  120. sdmxlib-0.67.0/src/sdmxlib/model/_interning.py +0 -34
  121. sdmxlib-0.67.0/src/sdmxlib/model/category.py +0 -286
  122. sdmxlib-0.67.0/src/sdmxlib/model/codelist.py +0 -537
  123. sdmxlib-0.67.0/src/sdmxlib/model/constraint.py +0 -249
  124. sdmxlib-0.67.0/src/sdmxlib/model/errors.py +0 -38
  125. sdmxlib-0.67.0/src/sdmxlib/model/mapping.py +0 -473
  126. sdmxlib-0.67.0/src/sdmxlib/model/metadataflow.py +0 -65
  127. sdmxlib-0.67.0/src/sdmxlib/model/metadatastructure.py +0 -399
  128. sdmxlib-0.67.0/src/sdmxlib/model/organisation.py +0 -372
  129. sdmxlib-0.67.0/src/sdmxlib/model/representation.py +0 -100
  130. sdmxlib-0.67.0/src/sdmxlib/model/validation.py +0 -2189
  131. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/README.md +0 -0
  132. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/_duckdb.py +0 -0
  133. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/_singleflight.py +0 -0
  134. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/__init__.py +0 -0
  135. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/_freshness.py +0 -0
  136. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/filters.py +0 -0
  137. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/policy.py +0 -0
  138. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/api/providers.py +0 -0
  139. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/builders/__init__.py +0 -0
  140. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/builders/metadata_annotation.py +0 -0
  141. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/data_store.py +0 -0
  142. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/_arrow.py +0 -0
  143. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/_coerce.py +0 -0
  144. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/_index.py +0 -0
  145. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/data_format.py +0 -0
  146. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_csv/__init__.py +0 -0
  147. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_csv/writer.py +0 -0
  148. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json/__init__.py +0 -0
  149. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_json_1_0/__init__.py +0 -0
  150. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml/__init__.py +0 -0
  151. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml21/__init__.py +0 -0
  152. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml21/namespaces.py +0 -0
  153. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml30/__init__.py +0 -0
  154. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml30/namespaces.py +0 -0
  155. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml31/__init__.py +0 -0
  156. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/formats/sdmx_ml31/namespaces.py +0 -0
  157. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/local/__init__.py +0 -0
  158. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/local/data_store.py +0 -0
  159. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/local/sql.py +0 -0
  160. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/_label_match.py +0 -0
  161. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/istring.py +0 -0
  162. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/model/rest_api.py +0 -0
  163. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/py.typed +0 -0
  164. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/__init__.py +0 -0
  165. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_closure.py +0 -0
  166. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_joins.py +0 -0
  167. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_plan.py +0 -0
  168. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_pushdown.py +0 -0
  169. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_rebase.py +0 -0
  170. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/_rest.py +0 -0
  171. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/observations.py +0 -0
  172. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/raw.py +0 -0
  173. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/query/schema.py +0 -0
  174. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/rest.py +0 -0
  175. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/session.py +0 -0
  176. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/sql.py +0 -0
  177. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/__init__.py +0 -0
  178. {sdmxlib-0.67.0 → sdmxlib-0.68.0}/src/sdmxlib/storage/_projections.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sdmxlib
3
- Version: 0.67.0
3
+ Version: 0.68.0
4
4
  Summary: SDMX structural metadata library for Python
5
5
  Keywords: sdmx,statistics,metadata,datastructure
6
6
  Author: gabrielgellner
@@ -10,16 +10,17 @@ Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Intended Audience :: Developers
11
11
  Classifier: Intended Audience :: Science/Research
12
12
  Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
14
14
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
15
15
  Requires-Dist: attrs>=26.1.0
16
- Requires-Dist: duckdb>=1.5.5
16
+ Requires-Dist: duckdb>=1.5.6
17
17
  Requires-Dist: httpx>=0.28.1
18
18
  Requires-Dist: lxml>=6.0.2
19
19
  Requires-Dist: msgspec>=0.19
20
20
  Requires-Dist: polars>=1.39.3
21
21
  Requires-Dist: pyarrow>=18.0.0
22
- Requires-Python: >=3.13
22
+ Requires-Dist: typing-extensions>=4.13
23
+ Requires-Python: >=3.14
23
24
  Project-URL: Homepage, https://gitlab.com/pinax-suite/sdmxlib
24
25
  Project-URL: Repository, https://gitlab.com/pinax-suite/sdmxlib
25
26
  Project-URL: Documentation, https://pinax-suite.gitlab.io/sdmxlib
@@ -1,9 +1,9 @@
1
1
  [project]
2
2
  name = "sdmxlib"
3
- version = "0.67.0"
3
+ version = "0.68.0"
4
4
  description = "SDMX structural metadata library for Python"
5
5
  readme = "README.md"
6
- requires-python = ">=3.13"
6
+ requires-python = ">=3.14"
7
7
  keywords = [
8
8
  "sdmx",
9
9
  "statistics",
@@ -15,17 +15,18 @@ classifiers = [
15
15
  "Intended Audience :: Developers",
16
16
  "Intended Audience :: Science/Research",
17
17
  "Programming Language :: Python :: 3",
18
- "Programming Language :: Python :: 3.13",
18
+ "Programming Language :: Python :: 3.14",
19
19
  "Topic :: Scientific/Engineering :: Information Analysis",
20
20
  ]
21
21
  dependencies = [
22
22
  "attrs>=26.1.0",
23
- "duckdb>=1.5.5",
23
+ "duckdb>=1.5.6",
24
24
  "httpx>=0.28.1",
25
25
  "lxml>=6.0.2",
26
26
  "msgspec>=0.19",
27
27
  "polars>=1.39.3",
28
28
  "pyarrow>=18.0.0",
29
+ "typing-extensions>=4.13",
29
30
  ]
30
31
 
31
32
  [project.license]
@@ -42,7 +43,7 @@ Documentation = "https://pinax-suite.gitlab.io/sdmxlib"
42
43
  Changelog = "https://gitlab.com/pinax-suite/sdmxlib/-/blob/main/CHANGELOG.md"
43
44
 
44
45
  [build-system]
45
- requires = ["uv_build>=0.12.0,<0.13.0"]
46
+ requires = ["uv_build>=0.13.0,<0.14.0"]
46
47
  build-backend = "uv_build"
47
48
 
48
49
  [tool.pytest.ini_options]
@@ -54,6 +55,7 @@ markers = [
54
55
  "docs: tests that verify documentation examples",
55
56
  "integration: end-to-end tests replayed from VCR cassettes; no network",
56
57
  "slow: tests that dominate suite wall-time; deselect for tight loops",
58
+ "serial: thread-heavy tests `just test` runs alone, after the parallel phase; under -n they starve",
57
59
  "bench: performance benchmarks; excluded from default test runs",
58
60
  "bundle: benchmarks against a real SDMX bundle; need $SDMXLIB_BENCH_BUNDLE",
59
61
  ]
@@ -92,6 +94,8 @@ pytest_add_cli_args = [
92
94
  ]
93
95
  pytest_add_cli_args_test_selection = ["tests/unit"]
94
96
  mutate_only_covered_lines = false
97
+ process_isolation = "forkserver"
98
+ forkserver_warmup = "none"
95
99
 
96
100
  [dependency-groups]
97
101
  dev = [
@@ -103,22 +107,22 @@ dev = [
103
107
  "mkdocstrings[python]>=1.0.3",
104
108
  "polars>=1.39.3",
105
109
  "pytest>=9.0.2",
106
- "jsonschema>=4.21.0",
110
+ "jsonschema[format-nongpl]>=4.21.0",
107
111
  "pytest-benchmark>=4.0.0",
108
112
  "pytest-cov>=7.1.0",
109
113
  "pytest-xdist>=3.8.0",
110
114
  "pytest-memray>=1.7.0",
111
115
  "pytest-recording>=0.13.4",
112
- "pydoclint>=0.9.1,<0.10",
113
- "pyrefly>=1.2.0,<1.3",
114
- "ruff>=0.16.1,<0.17",
115
- "mutmut>=3.3,<4",
116
+ "pydoclint>=0.11.1,<0.12",
117
+ "pyrefly>=1.4.0,<1.5",
118
+ "ruff>=0.17.1,<0.18",
119
+ "mutmut>=3.8,<4",
116
120
  "hypothesis>=6.140,<7",
117
121
  "sqlglot>=27.0",
118
122
  "fastapi>=0.115",
119
123
  "httpx2>=2.12",
120
124
  ]
121
125
  bench-compete = [
122
- "sdmx1>=2.18.0",
123
- "pysdmx[xml]>=1.0.0",
126
+ "sdmx1>=2.27.0",
127
+ "pysdmx[xml,json]>=1.20.0",
124
128
  ]
@@ -1,18 +1,18 @@
1
1
  [project]
2
2
  name = "sdmxlib"
3
- version = "0.67.0"
3
+ version = "0.68.0"
4
4
  description = "SDMX structural metadata library for Python"
5
5
  readme = "README.md"
6
6
  license = { text = "Apache-2.0" }
7
7
  authors = [{ name = "gabrielgellner", email = "gabrielgellner@gmail.com" }]
8
- requires-python = ">=3.13"
8
+ requires-python = ">=3.14"
9
9
  keywords = ["sdmx", "statistics", "metadata", "datastructure"]
10
10
  classifiers = [
11
11
  "Development Status :: 4 - Beta",
12
12
  "Intended Audience :: Developers",
13
13
  "Intended Audience :: Science/Research",
14
14
  "Programming Language :: Python :: 3",
15
- "Programming Language :: Python :: 3.13",
15
+ "Programming Language :: Python :: 3.14",
16
16
  "Topic :: Scientific/Engineering :: Information Analysis",
17
17
  ]
18
18
  dependencies = [
@@ -26,12 +26,22 @@ dependencies = [
26
26
  # taken on their own merits. It is **not** a fix for #400: 1.5.0, 1.5.1,
27
27
  # 1.5.2, 1.5.3, 1.5.4, 1.5.5 and 1.6.0.dev379 all read the affected bundle
28
28
  # identically, so that defect is in the file rather than in the reader.
29
- "duckdb>=1.5.5",
29
+ #
30
+ # >=1.5.6: test_annotation_subtree_read (#426) asserts the annotation
31
+ # subtree read uses the owner index. 1.5.5's planner chooses a SEQ_SCAN
32
+ # over `owner_artefact_urn = ?` (502 rows read) and 1.5.6 uses the index,
33
+ # so on 1.5.5 the read scans every annotation row.
34
+ "duckdb>=1.5.6",
30
35
  "httpx>=0.28.1",
31
36
  "lxml>=6.0.2",
32
37
  "msgspec>=0.19",
33
38
  "polars>=1.39.3",
34
39
  "pyarrow>=18.0.0",
40
+ # PEP 728's `closed=True` TypedDict, which `typing` gains only in 3.15: a
41
+ # TypedDict unpacked into a constructor (`**read_reference_attrs(el)`) must
42
+ # be closed for a checker to know it holds no other key. httpx already
43
+ # brings it in, through anyio; declared because we now import it.
44
+ "typing-extensions>=4.13",
35
45
  ]
36
46
 
37
47
  [project.urls]
@@ -41,7 +51,7 @@ Documentation = "https://pinax-suite.gitlab.io/sdmxlib"
41
51
  Changelog = "https://gitlab.com/pinax-suite/sdmxlib/-/blob/main/CHANGELOG.md"
42
52
 
43
53
  [build-system]
44
- requires = ["uv_build>=0.12.0,<0.13.0"]
54
+ requires = ["uv_build>=0.13.0,<0.14.0"]
45
55
  build-backend = "uv_build"
46
56
 
47
57
  [tool.pytest.ini_options]
@@ -71,6 +81,7 @@ markers = [
71
81
  "docs: tests that verify documentation examples",
72
82
  "integration: end-to-end tests replayed from VCR cassettes; no network",
73
83
  "slow: tests that dominate suite wall-time; deselect for tight loops",
84
+ "serial: thread-heavy tests `just test` runs alone, after the parallel phase; under -n they starve",
74
85
  "bench: performance benchmarks; excluded from default test runs",
75
86
  # The bundle tier (#379) reads a real 2.6 GB SDMX bundle that is not, and
76
87
  # cannot be, in the repo. Split from `bench` so `just bench` means the same
@@ -111,16 +122,18 @@ dev = [
111
122
  "mkdocstrings[python]>=1.0.3",
112
123
  "polars>=1.39.3",
113
124
  "pytest>=9.0.2",
114
- "jsonschema>=4.21.0",
125
+ "jsonschema[format-nongpl]>=4.21.0",
115
126
  "pytest-benchmark>=4.0.0",
116
127
  "pytest-cov>=7.1.0",
117
128
  "pytest-xdist>=3.8.0",
118
129
  "pytest-memray>=1.7.0",
119
130
  "pytest-recording>=0.13.4",
120
- "pydoclint>=0.9.1,<0.10",
121
- "pyrefly>=1.2.0,<1.3",
122
- "ruff>=0.16.1,<0.17",
123
- "mutmut>=3.3,<4",
131
+ "pydoclint>=0.11.1,<0.12",
132
+ "pyrefly>=1.4.0,<1.5",
133
+ "ruff>=0.17.1,<0.18",
134
+ # 3.8: `process_isolation = "forkserver"`, which `tools/mutmut_forksafe.py`
135
+ # builds on, and the `state()` its import-time credit reads.
136
+ "mutmut>=3.8,<4",
124
137
  "hypothesis>=6.140,<7",
125
138
  # Test-only, and must stay that way: the SQL-AST invariants in
126
139
  # tests/support/sql_ast.py parse emitted statements to assert structural
@@ -142,11 +155,12 @@ dev = [
142
155
  "httpx2>=2.12",
143
156
  ]
144
157
  # Optional: third-party SDMX libraries for the competitive benchmarks
145
- # (tests/bench/test_compete.py). Install via `uv sync --group bench-compete`.
158
+ # (tests/bench/test_compete.py, and `just bench-compete` — bench/compete/).
159
+ # Install via `uv sync --group bench-compete`.
146
160
  # Kept out of `dev` so default contributor sync stays lean.
147
161
  bench-compete = [
148
- "sdmx1>=2.18.0",
149
- "pysdmx[xml]>=1.0.0",
162
+ "sdmx1>=2.27.0",
163
+ "pysdmx[xml,json]>=1.20.0",
150
164
  ]
151
165
 
152
166
  [tool.mutmut]
@@ -200,3 +214,16 @@ pytest_add_cli_args_test_selection = ["tests/unit"]
200
214
  # The cost of leaving it off is that uncovered lines also get mutants, which
201
215
  # survive for an uninteresting reason -- factor that into any score.
202
216
  mutate_only_covered_lines = false
217
+ # Keep pytest out of the forking parent (#314). In the default `fork` mode
218
+ # mutmut runs the suite in-process before forking the mutants. One polars
219
+ # operation there makes every later child hang until its CPU limit, and the
220
+ # hang is booked as a timeout. `tools/mutmut_forksafe.py` refuses to run
221
+ # without this.
222
+ process_isolation = "forkserver"
223
+ # And nothing imported before the mutant is chosen. The default warm-up
224
+ # collects the suite once in the fork server, before any mutant is active, and
225
+ # every child inherits those modules. Code that runs at import (the 3.x
226
+ # readers' and writers' module-level instances, `gaps.py`'s table) is then
227
+ # never mutated. Its mutants are booked as survivors: 282 for `_v3_writer.py`,
228
+ # where a fresh process kills `__init__`'s outright (#458).
229
+ forkserver_warmup = "none"
@@ -6,7 +6,7 @@ from sdmxlib.api.policy import RegistryUnavailable
6
6
  from sdmxlib.api.providers import Provider
7
7
  from sdmxlib.api.query import DataQuery
8
8
  from sdmxlib.formats.data_format import DataFormat
9
- from sdmxlib.formats.gaps import Gap, unrepresentable
9
+ from sdmxlib.formats.gaps import DroppedArtefact, Gap, dropped, unrepresentable
10
10
  from sdmxlib.api.client import ResponseTooLargeError
11
11
  from sdmxlib.api.registry import BearerToken, FmrRegistry, RestRegistry
12
12
  from sdmxlib.data_store import DataStore, WriteSource
@@ -17,6 +17,8 @@ from sdmxlib.model.rest_api import ApiVersion
17
17
  from sdmxlib.model.rollup import AncestorMap
18
18
  from sdmxlib.session import Session, SessionHook, ValueSet
19
19
  from sdmxlib.query import RawSql, RawSqlError, schema
20
+ from sdmxlib import versions
21
+ from sdmxlib.versions import RewrittenVersion, VersionRewrite
20
22
  from sdmxlib.query.accessors import ArtefactRow, CodeRow, HCodeRow, ReportedAttributeRow, q
21
23
  from sdmxlib.query._compile import CompiledQuery
22
24
  from sdmxlib.query._expr import Agg, AggPred, AnyPred, Col, Cols, Cursor, Pred, RowKind, Untyped, Win, WinFn, WinPred
@@ -29,20 +31,27 @@ from sdmxlib.local.data_store import DuckDBDataStore, DuckLakeVersionError
29
31
  from sdmxlib.rest import ComponentFilter, parse_components, widen_key
30
32
  from sdmxlib.query._common import Descending
31
33
  from sdmxlib.model.convert import from_dict, to_dict
34
+ from sdmxlib.model.errors import ImRuleWarning, ReadAssumption, ReadGap, SdmxWarning
32
35
  from sdmxlib.model.validation import (
36
+ LossyReadError,
33
37
  ReferenceIssue,
34
38
  ReferenceValidationError,
35
39
  SdmxParseError,
36
40
  ValidationError,
37
41
  ValidationIssue,
38
42
  validate,
39
- validate_message,
40
43
  validate_references,
41
44
  )
42
45
  from sdmxlib.model import (
46
+ ActionType,
47
+ Header,
48
+ MetadataHeader,
49
+ Party,
50
+ Sender,
43
51
  Agency,
44
52
  AgencyScheme,
45
53
  Annotation,
54
+ AnnotationURL,
46
55
  Annotations,
47
56
  ArtefactList,
48
57
  AttachmentLevel,
@@ -56,25 +65,50 @@ from sdmxlib.model import (
56
65
  CodeSelection,
57
66
  Codelist,
58
67
  CodelistExtension,
68
+ GeoFeatureSetCode,
69
+ GeoGridCode,
70
+ GeoGridCodelist,
71
+ GeographicCodelist,
59
72
  CodelistLike,
73
+ EnumerationLike,
74
+ ValueItem,
75
+ ValueList,
60
76
  Concept,
61
77
  ConceptScheme,
78
+ ISOConceptReference,
62
79
  CategorySchemeMap,
63
80
  ComponentMap,
81
+ DatePatternMap,
82
+ EpochMap,
83
+ EpochPeriod,
84
+ FixedValueMap,
85
+ FrequencyFormatMapping,
86
+ ResolvePeriod,
87
+ ToValueType,
64
88
  ConceptSchemeMap,
89
+ OrganisationSchemeMap,
65
90
  AttachmentConstraint,
91
+ AvailabilityConstraint,
66
92
  ConstraintAttachment,
93
+ DataSetReference,
94
+ QueryableDataSource,
67
95
  ConstraintType,
68
96
  Contact,
69
97
  DataConstraint,
70
98
  DataKey,
99
+ DataKeySet,
100
+ ComponentValueSet,
71
101
  CubeRegion,
72
102
  ReferencePeriod,
73
103
  ReleaseCalendar,
104
+ DataConsumer,
105
+ DataConsumerScheme,
74
106
  DataProvider,
75
107
  DataProviderScheme,
76
108
  MetadataProvider,
77
109
  MetadataProviderScheme,
110
+ OrganisationUnit,
111
+ OrganisationUnitScheme,
78
112
  DataStructure,
79
113
  Dataset,
80
114
  Dataflow,
@@ -89,7 +123,6 @@ from sdmxlib.model import (
89
123
  HierarchyAssociation,
90
124
  Group,
91
125
  InclusionMode,
92
- IndexValueMap,
93
126
  InMemoryRegistry,
94
127
  InternationalString,
95
128
  ItemExpr,
@@ -97,8 +130,13 @@ from sdmxlib.model import (
97
130
  ItemMap,
98
131
  ItemPredicate,
99
132
  KeyValue,
133
+ RegionValue,
134
+ TimeBound,
135
+ TimeRange,
100
136
  Level,
101
- LiteralValueMap,
137
+ Link,
138
+ RepresentationMapping,
139
+ SourceValue,
102
140
  item,
103
141
  Maintainable,
104
142
  MaintainableArtefact,
@@ -107,6 +145,7 @@ from sdmxlib.model import (
107
145
  Measure,
108
146
  MemberValue,
109
147
  MeasureDimension,
148
+ MetadataAttributeUsage,
110
149
  MetadataAttribute,
111
150
  MetadataMessage,
112
151
  MetadataProvisionAgreement,
@@ -119,8 +158,9 @@ from sdmxlib.model import (
119
158
  ReportedAttributeValue,
120
159
  DataType,
121
160
  Facet,
161
+ SentinelValue,
122
162
  Ref,
123
- RegexValueMap,
163
+ Refusal,
124
164
  RegistryReader,
125
165
  Representation,
126
166
  RepresentationMap,
@@ -131,7 +171,6 @@ from sdmxlib.model import (
131
171
  StructureMessage,
132
172
  TimeDimension,
133
173
  UnresolvedRef,
134
- ValueMap,
135
174
  AmbiguousHierarchyError,
136
175
  artefact_urn,
137
176
  )
@@ -158,6 +197,7 @@ def len[R: RowKind]() -> Agg[R]: # noqa: A001 - polars' `pl.len()`; nothing in
158
197
 
159
198
 
160
199
  __all__ = [
200
+ "ActionType",
161
201
  "Agency",
162
202
  "AgencyScheme",
163
203
  "Agg",
@@ -165,6 +205,7 @@ __all__ = [
165
205
  "AmbiguousHierarchyError",
166
206
  "AncestorMap",
167
207
  "Annotation",
208
+ "AnnotationURL",
168
209
  "Annotations",
169
210
  "AnyPred",
170
211
  "ApiVersion",
@@ -174,6 +215,7 @@ __all__ = [
174
215
  "AttachmentLevel",
175
216
  "Attribute",
176
217
  "AttributeUsage",
218
+ "AvailabilityConstraint",
177
219
  "BearerToken",
178
220
  "CascadeSelection",
179
221
  "Categorisation",
@@ -192,6 +234,7 @@ __all__ = [
192
234
  "ComponentFilter",
193
235
  "ComponentMap",
194
236
  "ComponentRole",
237
+ "ComponentValueSet",
195
238
  "Concept",
196
239
  "ConceptScheme",
197
240
  "ConceptSchemeMap",
@@ -201,11 +244,15 @@ __all__ = [
201
244
  "CubeRegion",
202
245
  "Cursor",
203
246
  "DataConstraint",
247
+ "DataConsumer",
248
+ "DataConsumerScheme",
204
249
  "DataFormat",
205
250
  "DataKey",
251
+ "DataKeySet",
206
252
  "DataProvider",
207
253
  "DataProviderScheme",
208
254
  "DataQuery",
255
+ "DataSetReference",
209
256
  "DataStore",
210
257
  "DataStructure",
211
258
  "DataType",
@@ -213,28 +260,41 @@ __all__ = [
213
260
  "DataflowBinding",
214
261
  "DataflowEntry",
215
262
  "Dataset",
263
+ "DatePatternMap",
216
264
  "Descending",
217
265
  "DimFilter",
218
266
  "Dimension",
219
267
  "DriftError",
220
268
  "DriftIssue",
269
+ "DroppedArtefact",
221
270
  "DuckDBDataStore",
222
271
  "DuckLakeVersionError",
272
+ "EnumerationLike",
273
+ "EpochMap",
274
+ "EpochPeriod",
223
275
  "Facet",
224
276
  "FederatedRegistry",
277
+ "FixedValueMap",
225
278
  "FmrRegistry",
226
279
  "Frame",
280
+ "FrequencyFormatMapping",
227
281
  "Gap",
282
+ "GeoFeatureSetCode",
283
+ "GeoGridCode",
284
+ "GeoGridCodelist",
285
+ "GeographicCodelist",
228
286
  "Group",
229
287
  "Grouped",
230
288
  "HCodeRow",
289
+ "Header",
231
290
  "HierarchicalCode",
232
291
  "HierarchicalCodelist",
233
292
  "Hierarchy",
234
293
  "HierarchyAssociation",
294
+ "ISOConceptReference",
295
+ "ImRuleWarning",
235
296
  "InMemoryRegistry",
236
297
  "InclusionMode",
237
- "IndexValueMap",
238
298
  "InternationalString",
239
299
  "ItemExpr",
240
300
  "ItemList",
@@ -244,14 +304,17 @@ __all__ = [
244
304
  "LazyCodelist",
245
305
  "LazyHierarchy",
246
306
  "Level",
247
- "LiteralValueMap",
307
+ "Link",
248
308
  "LocalRegistry",
309
+ "LossyReadError",
249
310
  "Maintainable",
250
311
  "MaintainableArtefact",
251
312
  "Measure",
252
313
  "MeasureDimension",
253
314
  "MemberValue",
254
315
  "MetadataAttribute",
316
+ "MetadataAttributeUsage",
317
+ "MetadataHeader",
255
318
  "MetadataMessage",
256
319
  "MetadataProvider",
257
320
  "MetadataProviderScheme",
@@ -262,19 +325,27 @@ __all__ = [
262
325
  "Metadataflow",
263
326
  "ObsQuery",
264
327
  "ObsRow",
328
+ "OrganisationSchemeMap",
329
+ "OrganisationUnit",
330
+ "OrganisationUnitScheme",
265
331
  "Page",
332
+ "Party",
266
333
  "Pred",
267
334
  "Provider",
268
335
  "ProvisionAgreement",
269
336
  "Query",
270
337
  "QueryPlan",
338
+ "QueryableDataSource",
271
339
  "RawSql",
272
340
  "RawSqlError",
341
+ "ReadAssumption",
342
+ "ReadGap",
273
343
  "Ref",
274
344
  "ReferenceIssue",
275
345
  "ReferencePeriod",
276
346
  "ReferenceValidationError",
277
- "RegexValueMap",
347
+ "Refusal",
348
+ "RegionValue",
278
349
  "RegistryReader",
279
350
  "RegistryUnavailable",
280
351
  "ReleaseCalendar",
@@ -283,33 +354,46 @@ __all__ = [
283
354
  "ReportedAttributeValue",
284
355
  "Representation",
285
356
  "RepresentationMap",
357
+ "RepresentationMapping",
358
+ "ResolvePeriod",
286
359
  "ResponseTooLargeError",
287
360
  "RestRegistry",
361
+ "RewrittenVersion",
288
362
  "RowKind",
289
363
  "SchemaInspector",
290
364
  "SdmxParseError",
291
365
  "SdmxRef",
292
366
  "SdmxUrn",
367
+ "SdmxWarning",
368
+ "Sender",
369
+ "SentinelValue",
293
370
  "Session",
294
371
  "SessionHook",
372
+ "SourceValue",
295
373
  "SqlRelation",
296
374
  "StructureMap",
297
375
  "StructureMessage",
298
376
  "StructureSet",
299
377
  "SupportsUrn",
378
+ "TimeBound",
300
379
  "TimeDimension",
380
+ "TimeRange",
381
+ "ToValueType",
301
382
  "UnresolvedRef",
302
383
  "Untyped",
303
384
  "ValidationError",
304
385
  "ValidationIssue",
305
- "ValueMap",
386
+ "ValueItem",
387
+ "ValueList",
306
388
  "ValueSet",
389
+ "VersionRewrite",
307
390
  "Win",
308
391
  "WinFn",
309
392
  "WinPred",
310
393
  "WriteSource",
311
394
  "artefact_urn",
312
395
  "dim",
396
+ "dropped",
313
397
  "from_dict",
314
398
  "item",
315
399
  "len",
@@ -325,7 +409,7 @@ __all__ = [
325
409
  "union",
326
410
  "unrepresentable",
327
411
  "validate",
328
- "validate_message",
329
412
  "validate_references",
413
+ "versions",
330
414
  "widen_key",
331
415
  ]
@@ -87,3 +87,31 @@ def from_storage(value: datetime | None) -> datetime | None:
87
87
  if value.tzinfo is not None:
88
88
  return value
89
89
  return value.replace(tzinfo=UTC)
90
+
91
+
92
+ @overload
93
+ def as_utc(value: datetime) -> datetime: ...
94
+ @overload
95
+ def as_utc(value: None) -> None: ...
96
+ def as_utc(value: datetime | None) -> datetime | None:
97
+ """A datetime as the *model* holds it: the instant, tagged UTC (#440).
98
+
99
+ The attrs converter on every model `datetime`. The store already returned
100
+ this form (`from_storage`), but the model held whatever a reader handed
101
+ it — a naive value for an unqualified `xs:dateTime` — so an artefact read
102
+ from a document was not equal to the same artefact read back from the
103
+ store. Normalising at the model boundary makes the two the same object,
104
+ by the reading this module already chose: a naive value is UTC.
105
+
106
+ Args:
107
+ value: Any datetime, aware or naive. `None` passes through.
108
+
109
+ Returns:
110
+ The same instant, tz-aware in UTC: a naive value is labelled, an aware
111
+ one converted.
112
+ """
113
+ if value is None:
114
+ return None
115
+ if value.tzinfo is None:
116
+ return value.replace(tzinfo=UTC)
117
+ return value.astimezone(UTC)