datamasque-python 1.1.2__tar.gz → 1.1.4__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 (77) hide show
  1. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/HISTORY.rst +14 -0
  2. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/PKG-INFO +1 -1
  3. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/__init__.py +2 -0
  4. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/connection.py +29 -0
  5. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/pyproject.toml +1 -1
  6. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/setup.cfg +1 -1
  7. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_connections.py +106 -0
  8. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/uv.lock +90 -90
  9. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.editorconfig +0 -0
  10. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.github/workflows/ci.yml +0 -0
  11. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.github/workflows/release-testpypi.yml +0 -0
  12. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.github/workflows/release.yml +0 -0
  13. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.gitignore +0 -0
  14. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/.readthedocs.yaml +0 -0
  15. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/CONTRIBUTING.rst +0 -0
  16. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/LICENSE +0 -0
  17. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/MANIFEST.in +0 -0
  18. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/Makefile +0 -0
  19. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/NOTICE +0 -0
  20. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/README.rst +0 -0
  21. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/base.py +0 -0
  22. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/connections.py +0 -0
  23. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/discovery.py +0 -0
  24. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/discovery_configs.py +0 -0
  25. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/dmclient.py +0 -0
  26. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/exceptions.py +0 -0
  27. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/files.py +0 -0
  28. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/ifm.py +0 -0
  29. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/license.py +0 -0
  30. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/__init__.py +0 -0
  31. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/data_selection.py +0 -0
  32. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/discovery.py +0 -0
  33. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/discovery_config.py +0 -0
  34. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/dm_instance.py +0 -0
  35. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/files.py +0 -0
  36. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/git.py +0 -0
  37. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/ifm.py +0 -0
  38. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/license.py +0 -0
  39. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/pagination.py +0 -0
  40. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/ruleset.py +0 -0
  41. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/ruleset_library.py +0 -0
  42. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/runs.py +0 -0
  43. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/status.py +0 -0
  44. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/models/user.py +0 -0
  45. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/py.typed +0 -0
  46. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/ruleset_libraries.py +0 -0
  47. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/rulesets.py +0 -0
  48. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/runs.py +0 -0
  49. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/settings.py +0 -0
  50. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/datamasque/client/users.py +0 -0
  51. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/Makefile +0 -0
  52. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/client.models.rst +0 -0
  53. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/client.rst +0 -0
  54. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/conf.py +0 -0
  55. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/contributing.rst +0 -0
  56. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/history.rst +0 -0
  57. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/index.rst +0 -0
  58. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/installation.rst +0 -0
  59. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/make.bat +0 -0
  60. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/modules.rst +0 -0
  61. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/readme.rst +0 -0
  62. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/docs/usage.rst +0 -0
  63. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/__init__.py +0 -0
  64. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/conftest.py +0 -0
  65. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/helpers.py +0 -0
  66. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_base.py +0 -0
  67. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_discovery.py +0 -0
  68. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_discovery_configs.py +0 -0
  69. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_files.py +0 -0
  70. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_ifm.py +0 -0
  71. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_license.py +0 -0
  72. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_pagination.py +0 -0
  73. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_ruleset_library.py +0 -0
  74. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_rulesets.py +0 -0
  75. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_runs.py +0 -0
  76. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_settings.py +0 -0
  77. {datamasque_python-1.1.2 → datamasque_python-1.1.4}/tests/test_users.py +0 -0
@@ -2,6 +2,20 @@
2
2
  History
3
3
  =======
4
4
 
5
+ 1.1.4 (2026-06-29)
6
+ ------------------
7
+
8
+ * Added ``DatabaseType.saphana`` for SAP HANA support.
9
+
10
+ 1.1.3 (2026-06-26)
11
+ ------------------
12
+
13
+ * Added ``tls_ca_file`` and ``tls_allow_invalid_certificates`` to ``MongoConnectionConfig``,
14
+ serialized only when TLS is enabled (``tls_ca_file`` only when set,
15
+ ``tls_allow_invalid_certificates`` only when ``True``).
16
+ * Added ``DatabaseType.documentdb`` and ``DocumentDbConnectionConfig`` for AWS DocumentDB,
17
+ which is MongoDB wire-compatible and reuses ``MongoConnectionConfig`` (differing only by ``db_type``).
18
+
5
19
  1.1.2 (2026-06-26)
6
20
  ------------------
7
21
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamasque-python
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Official Python client for the DataMasque data-masking API.
5
5
  Project-URL: Homepage, https://datamasque.com/
6
6
  Project-URL: Documentation, https://datamasque-python.readthedocs.io/
@@ -33,6 +33,7 @@ from datamasque.client.models.connection import (
33
33
  DatabaseConnectionConfig,
34
34
  DatabaseType,
35
35
  DatabricksConnectionConfig,
36
+ DocumentDbConnectionConfig,
36
37
  DynamoConnectionConfig,
37
38
  FileConnectionConfig,
38
39
  MongoConnectionConfig,
@@ -150,6 +151,7 @@ __all__ = [
150
151
  "DiscoveryConfigNotFoundError",
151
152
  "DiscoveryConfigType",
152
153
  "DiscoveryMatch",
154
+ "DocumentDbConnectionConfig",
153
155
  "DynamoConnectionConfig",
154
156
  "FailedToStartError",
155
157
  "FileConnectionConfig",
@@ -44,9 +44,11 @@ class DatabaseType(Enum):
44
44
  mssql_linked = "mssql_linked"
45
45
  snowflake = "snowflake"
46
46
  mongodb = "mongodb"
47
+ documentdb = "documentdb"
47
48
  databricks_lakebase = "databricks_lakebase"
48
49
  databricks = "databricks"
49
50
  informix = "informix"
51
+ saphana = "saphana"
50
52
 
51
53
 
52
54
  class SnowflakeStageLocation(str, Enum):
@@ -160,6 +162,8 @@ class MongoConnectionConfig(ConnectionConfig):
160
162
  password: Optional[str] = None
161
163
  auth_source: str = "admin"
162
164
  tls: bool = False
165
+ tls_ca_file: str = ""
166
+ tls_allow_invalid_certificates: bool = False
163
167
  direct_connection: bool = False
164
168
  replica_set: str = ""
165
169
  is_read_only: bool = False
@@ -180,6 +184,13 @@ class MongoConnectionConfig(ConnectionConfig):
180
184
  d["dbpassword"] = password
181
185
  if not d.get("tls"):
182
186
  d.pop("tls", None)
187
+ d.pop("tls_ca_file", None)
188
+ d.pop("tls_allow_invalid_certificates", None)
189
+ else:
190
+ if not d.get("tls_ca_file"):
191
+ d.pop("tls_ca_file", None)
192
+ if not d.get("tls_allow_invalid_certificates"):
193
+ d.pop("tls_allow_invalid_certificates", None)
183
194
  if not d.get("direct_connection"):
184
195
  d.pop("direct_connection", None)
185
196
  if not d.get("replica_set"):
@@ -197,6 +208,23 @@ class MongoConnectionConfig(ConnectionConfig):
197
208
  return data
198
209
 
199
210
 
211
+ class DocumentDbConnectionConfig(MongoConnectionConfig):
212
+ """
213
+ Connection configuration for an AWS DocumentDB cluster.
214
+
215
+ DocumentDB is MongoDB wire-compatible,
216
+ so it reuses `MongoConnectionConfig` (including the TLS handling)
217
+ and only differs by `db_type`/`database_type`.
218
+ """
219
+
220
+ # Narrowing the inherited Literal is a deliberate Pydantic discriminator override.
221
+ db_type: Literal["documentdb"] = "documentdb" # type: ignore[assignment]
222
+
223
+ @property
224
+ def database_type(self) -> DatabaseType:
225
+ return DatabaseType.documentdb
226
+
227
+
200
228
  class SnowflakeConnectionConfig(ConnectionConfig):
201
229
  """
202
230
  Connection configuration for a Snowflake database.
@@ -430,6 +458,7 @@ FILE_TYPE_MAP: dict[str, type[FileConnectionConfig]] = {
430
458
  DB_TYPE_MAP: dict[str, type[ConnectionConfig]] = {
431
459
  DatabaseType.dynamodb.value: DynamoConnectionConfig,
432
460
  DatabaseType.mongodb.value: MongoConnectionConfig,
461
+ DatabaseType.documentdb.value: DocumentDbConnectionConfig,
433
462
  DatabaseType.snowflake.value: SnowflakeConnectionConfig,
434
463
  DatabaseType.mssql_linked.value: MssqlLinkedServerConnectionConfig,
435
464
  DatabaseType.databricks.value: DatabricksConnectionConfig,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datamasque-python"
3
- version = "1.1.2"
3
+ version = "1.1.4"
4
4
  description = "Official Python client for the DataMasque data-masking API."
5
5
  authors = [
6
6
  { name = "DataMasque Ltd" },
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 1.1.2
2
+ current_version = 1.1.3
3
3
  commit = True
4
4
  tag = True
5
5
 
@@ -10,6 +10,7 @@ from datamasque.client.models.connection import (
10
10
  DatabaseConnectionConfig,
11
11
  DatabaseType,
12
12
  DatabricksConnectionConfig,
13
+ DocumentDbConnectionConfig,
13
14
  DynamoConnectionConfig,
14
15
  MongoConnectionConfig,
15
16
  MountedShareConnectionConfig,
@@ -1201,6 +1202,111 @@ def test_connection_config_dispatch_picks_mongo_subclass():
1201
1202
  assert isinstance(validate_connection(payload), MongoConnectionConfig)
1202
1203
 
1203
1204
 
1205
+ def test_mongo_tls_ca_fields_emitted_when_tls_enabled():
1206
+ conn = MongoConnectionConfig(
1207
+ name="mongo",
1208
+ host="mongo.example",
1209
+ database="people",
1210
+ tls=True,
1211
+ tls_ca_file="/certs/rds-ca.pem",
1212
+ tls_allow_invalid_certificates=True,
1213
+ )
1214
+ d = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
1215
+ assert d["tls"] is True
1216
+ assert d["tls_ca_file"] == "/certs/rds-ca.pem"
1217
+ assert d["tls_allow_invalid_certificates"] is True
1218
+
1219
+
1220
+ def test_mongo_tls_ca_fields_omitted_when_unset_but_tls_enabled():
1221
+ conn = MongoConnectionConfig(name="mongo", host="mongo.example", database="people", tls=True)
1222
+ d = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
1223
+ assert d["tls"] is True
1224
+ assert "tls_ca_file" not in d
1225
+ assert "tls_allow_invalid_certificates" not in d
1226
+
1227
+
1228
+ def test_mongo_tls_ca_fields_omitted_when_tls_disabled():
1229
+ """Even when set, the TLS-dependent fields are not sent while TLS is disabled."""
1230
+ conn = MongoConnectionConfig(
1231
+ name="mongo",
1232
+ host="mongo.example",
1233
+ database="people",
1234
+ tls=False,
1235
+ tls_ca_file="/certs/rds-ca.pem",
1236
+ tls_allow_invalid_certificates=True,
1237
+ )
1238
+ d = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
1239
+ for absent in ("tls", "tls_ca_file", "tls_allow_invalid_certificates"):
1240
+ assert absent not in d
1241
+
1242
+
1243
+ def test_mongo_tls_ca_fields_roundtrip():
1244
+ payload = {
1245
+ "id": "mongo-tls-1",
1246
+ "name": "mongo",
1247
+ "mask_type": "database",
1248
+ "db_type": "mongodb",
1249
+ "host": "mongo.example",
1250
+ "database": "people",
1251
+ "tls": True,
1252
+ "tls_ca_file": "/certs/rds-ca.pem",
1253
+ "tls_allow_invalid_certificates": True,
1254
+ }
1255
+ conn = MongoConnectionConfig.model_validate(payload)
1256
+ assert conn.tls is True
1257
+ assert conn.tls_ca_file == "/certs/rds-ca.pem"
1258
+ assert conn.tls_allow_invalid_certificates is True
1259
+
1260
+
1261
+ def test_mongo_tls_ca_fields_default_when_missing():
1262
+ payload = {
1263
+ "id": "mongo-tls-2",
1264
+ "name": "mongo",
1265
+ "mask_type": "database",
1266
+ "db_type": "mongodb",
1267
+ "host": "mongo.example",
1268
+ "database": "people",
1269
+ }
1270
+ conn = MongoConnectionConfig.model_validate(payload)
1271
+ assert conn.tls_ca_file == ""
1272
+ assert conn.tls_allow_invalid_certificates is False
1273
+
1274
+
1275
+ def test_documentdb_connection_model_dump():
1276
+ conn = DocumentDbConnectionConfig(
1277
+ name="docdb",
1278
+ host="dtq-documentdb.cluster.example",
1279
+ database="people",
1280
+ user="dmadmin",
1281
+ password="hunter2",
1282
+ tls=True,
1283
+ tls_ca_file="/certs/rds-ca.pem",
1284
+ retry_writes=False,
1285
+ )
1286
+ d = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
1287
+ assert d["db_type"] == "documentdb"
1288
+ assert d["mask_type"] == "database"
1289
+ assert d["dbpassword"] == "hunter2"
1290
+ assert d["tls"] is True
1291
+ assert d["tls_ca_file"] == "/certs/rds-ca.pem"
1292
+ assert d["retry_writes"] is False
1293
+ assert conn.database_type is DatabaseType.documentdb
1294
+
1295
+
1296
+ def test_connection_config_dispatch_picks_documentdb_subclass():
1297
+ payload = {
1298
+ "id": "docdb-id-1",
1299
+ "name": "docdb",
1300
+ "mask_type": "database",
1301
+ "db_type": "documentdb",
1302
+ "host": "dtq-documentdb.cluster.example",
1303
+ "database": "people",
1304
+ }
1305
+ conn = validate_connection(payload)
1306
+ assert isinstance(conn, DocumentDbConnectionConfig)
1307
+ assert conn.database_type is DatabaseType.documentdb
1308
+
1309
+
1204
1310
  def test_database_connection_config_rejects_mongodb_database_type():
1205
1311
  """`DatabaseConnectionConfig` is for SQL engines; MongoDB users must use `MongoConnectionConfig`."""
1206
1312
  with pytest.raises(ValueError, match="For MongoDB"):
@@ -300,7 +300,7 @@ wheels = [
300
300
 
301
301
  [package.optional-dependencies]
302
302
  toml = [
303
- { name = "tomli", marker = "python_full_version < '3.10'" },
303
+ { name = "tomli" },
304
304
  ]
305
305
 
306
306
  [[package]]
@@ -423,12 +423,12 @@ wheels = [
423
423
 
424
424
  [package.optional-dependencies]
425
425
  toml = [
426
- { name = "tomli", marker = "python_full_version >= '3.10' and python_full_version <= '3.11'" },
426
+ { name = "tomli", marker = "python_full_version <= '3.11'" },
427
427
  ]
428
428
 
429
429
  [[package]]
430
430
  name = "datamasque-python"
431
- version = "1.1.2"
431
+ version = "1.1.4"
432
432
  source = { editable = "." }
433
433
  dependencies = [
434
434
  { name = "pydantic" },
@@ -503,7 +503,7 @@ name = "exceptiongroup"
503
503
  version = "1.3.1"
504
504
  source = { registry = "https://pypi.org/simple" }
505
505
  dependencies = [
506
- { name = "typing-extensions", marker = "python_full_version < '3.11'" },
506
+ { name = "typing-extensions" },
507
507
  ]
508
508
  sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
509
509
  wheels = [
@@ -518,7 +518,7 @@ resolution-markers = [
518
518
  "python_full_version < '3.10'",
519
519
  ]
520
520
  dependencies = [
521
- { name = "tzdata", marker = "python_full_version < '3.10'" },
521
+ { name = "tzdata" },
522
522
  ]
523
523
  sdist = { url = "https://files.pythonhosted.org/packages/3d/84/e95acaa848b855e15c83331d0401ee5f84b2f60889255c2e055cb4fb6bdf/faker-37.12.0.tar.gz", hash = "sha256:7505e59a7e02fa9010f06c3e1e92f8250d4cfbb30632296140c2d6dbef09b0fa", size = 1935741, upload-time = "2025-10-24T15:19:58.764Z" }
524
524
  wheels = [
@@ -535,7 +535,7 @@ resolution-markers = [
535
535
  "python_full_version == '3.10.*'",
536
536
  ]
537
537
  dependencies = [
538
- { name = "tzdata", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
538
+ { name = "tzdata", marker = "sys_platform == 'win32'" },
539
539
  ]
540
540
  sdist = { url = "https://files.pythonhosted.org/packages/70/03/14428edc541467c460d363f6e94bee9acc271f3e62470630fc9a647d0cf2/faker-40.8.0.tar.gz", hash = "sha256:936a3c9be6c004433f20aa4d99095df5dec82b8c7ad07459756041f8c1728875", size = 1956493, upload-time = "2026-03-04T16:18:48.161Z" }
541
541
  wheels = [
@@ -582,7 +582,7 @@ name = "importlib-metadata"
582
582
  version = "8.7.1"
583
583
  source = { registry = "https://pypi.org/simple" }
584
584
  dependencies = [
585
- { name = "zipp", marker = "python_full_version < '3.10'" },
585
+ { name = "zipp" },
586
586
  ]
587
587
  sdist = { url = "https://files.pythonhosted.org/packages/f3/49/3b30cad09e7771a4982d9975a8cbf64f00d4a1ececb53297f1d9a7be1b10/importlib_metadata-8.7.1.tar.gz", hash = "sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb", size = 57107, upload-time = "2025-12-21T10:00:19.278Z" }
588
588
  wheels = [
@@ -1070,13 +1070,13 @@ resolution-markers = [
1070
1070
  "python_full_version < '3.10'",
1071
1071
  ]
1072
1072
  dependencies = [
1073
- { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
1074
- { name = "exceptiongroup", marker = "python_full_version < '3.10'" },
1075
- { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
1076
- { name = "packaging", marker = "python_full_version < '3.10'" },
1077
- { name = "pluggy", marker = "python_full_version < '3.10'" },
1078
- { name = "pygments", marker = "python_full_version < '3.10'" },
1079
- { name = "tomli", marker = "python_full_version < '3.10'" },
1073
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1074
+ { name = "exceptiongroup" },
1075
+ { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } },
1076
+ { name = "packaging" },
1077
+ { name = "pluggy" },
1078
+ { name = "pygments" },
1079
+ { name = "tomli" },
1080
1080
  ]
1081
1081
  sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
1082
1082
  wheels = [
@@ -1093,13 +1093,13 @@ resolution-markers = [
1093
1093
  "python_full_version == '3.10.*'",
1094
1094
  ]
1095
1095
  dependencies = [
1096
- { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
1097
- { name = "exceptiongroup", marker = "python_full_version == '3.10.*'" },
1098
- { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
1099
- { name = "packaging", marker = "python_full_version >= '3.10'" },
1100
- { name = "pluggy", marker = "python_full_version >= '3.10'" },
1101
- { name = "pygments", marker = "python_full_version >= '3.10'" },
1102
- { name = "tomli", marker = "python_full_version == '3.10.*'" },
1096
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1097
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
1098
+ { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" } },
1099
+ { name = "packaging" },
1100
+ { name = "pluggy" },
1101
+ { name = "pygments" },
1102
+ { name = "tomli", marker = "python_full_version < '3.11'" },
1103
1103
  ]
1104
1104
  sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
1105
1105
  wheels = [
@@ -1200,24 +1200,24 @@ resolution-markers = [
1200
1200
  "python_full_version < '3.10'",
1201
1201
  ]
1202
1202
  dependencies = [
1203
- { name = "alabaster", version = "0.7.16", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
1204
- { name = "babel", marker = "python_full_version < '3.10'" },
1205
- { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
1206
- { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
1207
- { name = "imagesize", version = "1.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
1208
- { name = "importlib-metadata", marker = "python_full_version < '3.10'" },
1209
- { name = "jinja2", marker = "python_full_version < '3.10'" },
1210
- { name = "packaging", marker = "python_full_version < '3.10'" },
1211
- { name = "pygments", marker = "python_full_version < '3.10'" },
1212
- { name = "requests", marker = "python_full_version < '3.10'" },
1213
- { name = "snowballstemmer", marker = "python_full_version < '3.10'" },
1214
- { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.10'" },
1215
- { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.10'" },
1216
- { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.10'" },
1217
- { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.10'" },
1218
- { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.10'" },
1219
- { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.10'" },
1220
- { name = "tomli", marker = "python_full_version < '3.10'" },
1203
+ { name = "alabaster", version = "0.7.16", source = { registry = "https://pypi.org/simple" } },
1204
+ { name = "babel" },
1205
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1206
+ { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } },
1207
+ { name = "imagesize", version = "1.5.0", source = { registry = "https://pypi.org/simple" } },
1208
+ { name = "importlib-metadata" },
1209
+ { name = "jinja2" },
1210
+ { name = "packaging" },
1211
+ { name = "pygments" },
1212
+ { name = "requests" },
1213
+ { name = "snowballstemmer" },
1214
+ { name = "sphinxcontrib-applehelp" },
1215
+ { name = "sphinxcontrib-devhelp" },
1216
+ { name = "sphinxcontrib-htmlhelp" },
1217
+ { name = "sphinxcontrib-jsmath" },
1218
+ { name = "sphinxcontrib-qthelp" },
1219
+ { name = "sphinxcontrib-serializinghtml" },
1220
+ { name = "tomli" },
1221
1221
  ]
1222
1222
  sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911, upload-time = "2024-07-20T14:46:56.059Z" }
1223
1223
  wheels = [
@@ -1232,23 +1232,23 @@ resolution-markers = [
1232
1232
  "python_full_version == '3.10.*'",
1233
1233
  ]
1234
1234
  dependencies = [
1235
- { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
1236
- { name = "babel", marker = "python_full_version == '3.10.*'" },
1237
- { name = "colorama", marker = "python_full_version == '3.10.*' and sys_platform == 'win32'" },
1238
- { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
1239
- { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
1240
- { name = "jinja2", marker = "python_full_version == '3.10.*'" },
1241
- { name = "packaging", marker = "python_full_version == '3.10.*'" },
1242
- { name = "pygments", marker = "python_full_version == '3.10.*'" },
1243
- { name = "requests", marker = "python_full_version == '3.10.*'" },
1244
- { name = "snowballstemmer", marker = "python_full_version == '3.10.*'" },
1245
- { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.10.*'" },
1246
- { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.10.*'" },
1247
- { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.10.*'" },
1248
- { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.10.*'" },
1249
- { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.10.*'" },
1250
- { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.10.*'" },
1251
- { name = "tomli", marker = "python_full_version == '3.10.*'" },
1235
+ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" } },
1236
+ { name = "babel" },
1237
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1238
+ { name = "docutils", version = "0.21.2", source = { registry = "https://pypi.org/simple" } },
1239
+ { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" } },
1240
+ { name = "jinja2" },
1241
+ { name = "packaging" },
1242
+ { name = "pygments" },
1243
+ { name = "requests" },
1244
+ { name = "snowballstemmer" },
1245
+ { name = "sphinxcontrib-applehelp" },
1246
+ { name = "sphinxcontrib-devhelp" },
1247
+ { name = "sphinxcontrib-htmlhelp" },
1248
+ { name = "sphinxcontrib-jsmath" },
1249
+ { name = "sphinxcontrib-qthelp" },
1250
+ { name = "sphinxcontrib-serializinghtml" },
1251
+ { name = "tomli" },
1252
1252
  ]
1253
1253
  sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" }
1254
1254
  wheels = [
@@ -1263,23 +1263,23 @@ resolution-markers = [
1263
1263
  "python_full_version == '3.11.*'",
1264
1264
  ]
1265
1265
  dependencies = [
1266
- { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
1267
- { name = "babel", marker = "python_full_version == '3.11.*'" },
1268
- { name = "colorama", marker = "python_full_version == '3.11.*' and sys_platform == 'win32'" },
1269
- { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
1270
- { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.11.*'" },
1271
- { name = "jinja2", marker = "python_full_version == '3.11.*'" },
1272
- { name = "packaging", marker = "python_full_version == '3.11.*'" },
1273
- { name = "pygments", marker = "python_full_version == '3.11.*'" },
1274
- { name = "requests", marker = "python_full_version == '3.11.*'" },
1275
- { name = "roman-numerals", marker = "python_full_version == '3.11.*'" },
1276
- { name = "snowballstemmer", marker = "python_full_version == '3.11.*'" },
1277
- { name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.11.*'" },
1278
- { name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.11.*'" },
1279
- { name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.11.*'" },
1280
- { name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.11.*'" },
1281
- { name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.11.*'" },
1282
- { name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.11.*'" },
1266
+ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" } },
1267
+ { name = "babel" },
1268
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1269
+ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } },
1270
+ { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" } },
1271
+ { name = "jinja2" },
1272
+ { name = "packaging" },
1273
+ { name = "pygments" },
1274
+ { name = "requests" },
1275
+ { name = "roman-numerals" },
1276
+ { name = "snowballstemmer" },
1277
+ { name = "sphinxcontrib-applehelp" },
1278
+ { name = "sphinxcontrib-devhelp" },
1279
+ { name = "sphinxcontrib-htmlhelp" },
1280
+ { name = "sphinxcontrib-jsmath" },
1281
+ { name = "sphinxcontrib-qthelp" },
1282
+ { name = "sphinxcontrib-serializinghtml" },
1283
1283
  ]
1284
1284
  sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" }
1285
1285
  wheels = [
@@ -1294,23 +1294,23 @@ resolution-markers = [
1294
1294
  "python_full_version >= '3.12'",
1295
1295
  ]
1296
1296
  dependencies = [
1297
- { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
1298
- { name = "babel", marker = "python_full_version >= '3.12'" },
1299
- { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" },
1300
- { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
1301
- { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
1302
- { name = "jinja2", marker = "python_full_version >= '3.12'" },
1303
- { name = "packaging", marker = "python_full_version >= '3.12'" },
1304
- { name = "pygments", marker = "python_full_version >= '3.12'" },
1305
- { name = "requests", marker = "python_full_version >= '3.12'" },
1306
- { name = "roman-numerals", marker = "python_full_version >= '3.12'" },
1307
- { name = "snowballstemmer", marker = "python_full_version >= '3.12'" },
1308
- { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" },
1309
- { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" },
1310
- { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" },
1311
- { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" },
1312
- { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" },
1313
- { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" },
1297
+ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" } },
1298
+ { name = "babel" },
1299
+ { name = "colorama", marker = "sys_platform == 'win32'" },
1300
+ { name = "docutils", version = "0.22.4", source = { registry = "https://pypi.org/simple" } },
1301
+ { name = "imagesize", version = "2.0.0", source = { registry = "https://pypi.org/simple" } },
1302
+ { name = "jinja2" },
1303
+ { name = "packaging" },
1304
+ { name = "pygments" },
1305
+ { name = "requests" },
1306
+ { name = "roman-numerals" },
1307
+ { name = "snowballstemmer" },
1308
+ { name = "sphinxcontrib-applehelp" },
1309
+ { name = "sphinxcontrib-devhelp" },
1310
+ { name = "sphinxcontrib-htmlhelp" },
1311
+ { name = "sphinxcontrib-jsmath" },
1312
+ { name = "sphinxcontrib-qthelp" },
1313
+ { name = "sphinxcontrib-serializinghtml" },
1314
1314
  ]
1315
1315
  sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" }
1316
1316
  wheels = [