c2pa-python 0.35.1__tar.gz → 0.35.2__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.
- {c2pa_python-0.35.1/src/c2pa_python.egg-info → c2pa_python-0.35.2}/PKG-INFO +1 -1
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/pyproject.toml +1 -1
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa/c2pa.py +6 -6
- {c2pa_python-0.35.1 → c2pa_python-0.35.2/src/c2pa_python.egg-info}/PKG-INFO +1 -1
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/tests/test_unit_tests.py +113 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/LICENSE-APACHE +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/LICENSE-MIT +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/MANIFEST.in +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/README.md +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/requirements.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/scripts/download_artifacts.py +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/setup.cfg +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/setup.py +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa/__init__.py +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa/build.py +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa/lib.py +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa_python.egg-info/SOURCES.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa_python.egg-info/dependency_links.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa_python.egg-info/entry_points.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa_python.egg-info/requires.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/src/c2pa_python.egg-info/top_level.txt +0 -0
- {c2pa_python-0.35.1 → c2pa_python-0.35.2}/tests/test_unit_tests_threaded.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: c2pa-python
|
|
3
|
-
Version: 0.35.
|
|
3
|
+
Version: 0.35.2
|
|
4
4
|
Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
|
|
5
5
|
Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
|
|
6
6
|
Maintainer-email: Gavin Peacock <gpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "c2pa-python"
|
|
7
|
-
version = "0.35.
|
|
7
|
+
version = "0.35.2"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
description = "Python bindings for the C2PA Content Authenticity Initiative (CAI) library"
|
|
10
10
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
@@ -2263,6 +2263,9 @@ class Reader(ManagedResource):
|
|
|
2263
2263
|
if not context.is_valid:
|
|
2264
2264
|
raise C2paError("Context is not valid")
|
|
2265
2265
|
|
|
2266
|
+
if manifest_data is not None and not isinstance(manifest_data, bytes):
|
|
2267
|
+
raise TypeError(Reader._ERROR_MESSAGES['manifest_error'])
|
|
2268
|
+
|
|
2266
2269
|
# Determine format and open stream
|
|
2267
2270
|
supported = Reader.get_supported_mime_types()
|
|
2268
2271
|
|
|
@@ -2303,10 +2306,6 @@ class Reader(ManagedResource):
|
|
|
2303
2306
|
raise
|
|
2304
2307
|
|
|
2305
2308
|
if manifest_data is not None:
|
|
2306
|
-
if not isinstance(manifest_data, bytes):
|
|
2307
|
-
raise TypeError(
|
|
2308
|
-
Reader._ERROR_MESSAGES[
|
|
2309
|
-
'manifest_error'])
|
|
2310
2309
|
manifest_array = (
|
|
2311
2310
|
ctypes.c_ubyte *
|
|
2312
2311
|
len(manifest_data)).from_buffer_copy(manifest_data)
|
|
@@ -2322,14 +2321,15 @@ class Reader(ManagedResource):
|
|
|
2322
2321
|
len(manifest_data),
|
|
2323
2322
|
)
|
|
2324
2323
|
)
|
|
2325
|
-
# reader_ptr has been invalidated(consumed)
|
|
2326
2324
|
else:
|
|
2327
2325
|
# Consume reader with stream
|
|
2328
2326
|
new_ptr = _lib.c2pa_reader_with_stream(
|
|
2329
2327
|
reader_ptr, format_bytes,
|
|
2330
2328
|
self._own_stream._stream,
|
|
2331
2329
|
)
|
|
2332
|
-
|
|
2330
|
+
|
|
2331
|
+
# reader_ptr has been consumed by the FFI call.
|
|
2332
|
+
reader_ptr = None
|
|
2333
2333
|
|
|
2334
2334
|
self._handle = new_ptr
|
|
2335
2335
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: c2pa-python
|
|
3
|
-
Version: 0.35.
|
|
3
|
+
Version: 0.35.2
|
|
4
4
|
Summary: Python bindings for the C2PA Content Authenticity Initiative (CAI) library
|
|
5
5
|
Author-email: Gavin Peacock <gvnpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
|
|
6
6
|
Maintainer-email: Gavin Peacock <gpeacock@adobe.com>, Tania Mathern <mathern@adobe.com>
|
|
@@ -6041,6 +6041,119 @@ class TestReaderWithContext(TestContextAPIs):
|
|
|
6041
6041
|
context.close()
|
|
6042
6042
|
|
|
6043
6043
|
|
|
6044
|
+
class TestSidecarReader(TestContextAPIs):
|
|
6045
|
+
"""Reader over a detached (sidecar) manifest with a Context"""
|
|
6046
|
+
|
|
6047
|
+
def _make_detached_manifest(self):
|
|
6048
|
+
"""Sign DEFAULT_TEST_FILE with no-embed, return (asset_bytes,
|
|
6049
|
+
manifest_bytes) where manifest_bytes is the "detached" sidecar
|
|
6050
|
+
C2PA manifest."""
|
|
6051
|
+
|
|
6052
|
+
signer = self._ctx_make_signer()
|
|
6053
|
+
with open(DEFAULT_TEST_FILE, "rb") as f:
|
|
6054
|
+
asset_bytes = f.read()
|
|
6055
|
+
builder = Builder(self.test_manifest)
|
|
6056
|
+
builder.set_no_embed()
|
|
6057
|
+
# Output is discarded: with no-embed the asset is unchanged and the
|
|
6058
|
+
# manifest is returned by sign().
|
|
6059
|
+
manifest_bytes = builder.sign(
|
|
6060
|
+
signer, "image/jpeg", io.BytesIO(asset_bytes), io.BytesIO())
|
|
6061
|
+
builder.close()
|
|
6062
|
+
signer.close()
|
|
6063
|
+
self.assertIsInstance(manifest_bytes, bytes)
|
|
6064
|
+
self.assertGreater(len(manifest_bytes), 0)
|
|
6065
|
+
return asset_bytes, manifest_bytes
|
|
6066
|
+
|
|
6067
|
+
def test_reader_with_manifest_data_and_context(self):
|
|
6068
|
+
asset_bytes, manifest_bytes = self._make_detached_manifest()
|
|
6069
|
+
context = Context()
|
|
6070
|
+
reader = Reader(
|
|
6071
|
+
"image/jpeg",
|
|
6072
|
+
io.BytesIO(asset_bytes),
|
|
6073
|
+
manifest_bytes,
|
|
6074
|
+
context=context,
|
|
6075
|
+
)
|
|
6076
|
+
try:
|
|
6077
|
+
data = reader.json()
|
|
6078
|
+
self.assertTrue(data)
|
|
6079
|
+
self.assertFalse(reader.is_embedded())
|
|
6080
|
+
self.assertIn("manifests", json.loads(data))
|
|
6081
|
+
finally:
|
|
6082
|
+
reader.close()
|
|
6083
|
+
context.close()
|
|
6084
|
+
|
|
6085
|
+
def test_reader_manifest_data_context_invalid_manifest_raises(self):
|
|
6086
|
+
with open(DEFAULT_TEST_FILE, "rb") as f:
|
|
6087
|
+
asset_bytes = f.read()
|
|
6088
|
+
context = Context()
|
|
6089
|
+
reader = None
|
|
6090
|
+
try:
|
|
6091
|
+
with self.assertRaises(Error):
|
|
6092
|
+
reader = Reader(
|
|
6093
|
+
"image/jpeg",
|
|
6094
|
+
io.BytesIO(asset_bytes),
|
|
6095
|
+
b"not a real manifest",
|
|
6096
|
+
context=context,
|
|
6097
|
+
)
|
|
6098
|
+
# The consumed-pointer error branch must leave no usable handle.
|
|
6099
|
+
if reader is not None:
|
|
6100
|
+
self.assertEqual(
|
|
6101
|
+
reader._lifecycle_state, LifecycleState.CLOSED)
|
|
6102
|
+
self.assertIsNone(reader._handle)
|
|
6103
|
+
finally:
|
|
6104
|
+
if reader is not None:
|
|
6105
|
+
reader.close()
|
|
6106
|
+
context.close()
|
|
6107
|
+
|
|
6108
|
+
def test_reader_manifest_data_context_wrong_type_raises(self):
|
|
6109
|
+
with open(DEFAULT_TEST_FILE, "rb") as f:
|
|
6110
|
+
asset_bytes = f.read()
|
|
6111
|
+
context = Context()
|
|
6112
|
+
try:
|
|
6113
|
+
# Non-bytes manifest_data must raise TypeError before any native
|
|
6114
|
+
# reader handle is allocated (no leak on this path).
|
|
6115
|
+
with self.assertRaises(TypeError):
|
|
6116
|
+
Reader(
|
|
6117
|
+
"image/jpeg",
|
|
6118
|
+
io.BytesIO(asset_bytes),
|
|
6119
|
+
"manifest as str, not bytes",
|
|
6120
|
+
context=context,
|
|
6121
|
+
)
|
|
6122
|
+
finally:
|
|
6123
|
+
context.close()
|
|
6124
|
+
|
|
6125
|
+
def test_reader_manifest_data_context_use_after_close_raises(self):
|
|
6126
|
+
asset_bytes, manifest_bytes = self._make_detached_manifest()
|
|
6127
|
+
context = Context()
|
|
6128
|
+
reader = Reader(
|
|
6129
|
+
"image/jpeg",
|
|
6130
|
+
io.BytesIO(asset_bytes),
|
|
6131
|
+
manifest_bytes,
|
|
6132
|
+
context=context,
|
|
6133
|
+
)
|
|
6134
|
+
reader.close()
|
|
6135
|
+
self.assertEqual(reader._lifecycle_state, LifecycleState.CLOSED)
|
|
6136
|
+
with self.assertRaises(Error):
|
|
6137
|
+
reader.json()
|
|
6138
|
+
# Idempotent close after use-after-close attempt.
|
|
6139
|
+
reader.close()
|
|
6140
|
+
context.close()
|
|
6141
|
+
|
|
6142
|
+
def test_reader_manifest_data_context_as_context_manager(self):
|
|
6143
|
+
asset_bytes, manifest_bytes = self._make_detached_manifest()
|
|
6144
|
+
context = Context()
|
|
6145
|
+
with Reader(
|
|
6146
|
+
"image/jpeg",
|
|
6147
|
+
io.BytesIO(asset_bytes),
|
|
6148
|
+
manifest_bytes,
|
|
6149
|
+
context=context,
|
|
6150
|
+
) as reader:
|
|
6151
|
+
self.assertEqual(reader._lifecycle_state, LifecycleState.ACTIVE)
|
|
6152
|
+
self.assertTrue(reader.json())
|
|
6153
|
+
self.assertEqual(reader._lifecycle_state, LifecycleState.CLOSED)
|
|
6154
|
+
context.close()
|
|
6155
|
+
|
|
6156
|
+
|
|
6044
6157
|
class TestBuilderWithContext(TestContextAPIs):
|
|
6045
6158
|
|
|
6046
6159
|
def test_contextual_builder_with_default_context(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|