wrapture-instrumentation-postgresql 1.0.0.dev1__tar.gz → 1.0.0.dev2__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 (63) hide show
  1. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/PKG-INFO +3 -8
  2. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/README.md +1 -6
  3. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/pyproject.toml +1 -1
  4. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/__init__.py +1 -1
  5. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/asyncpg/README.md +3 -11
  6. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/asyncpg/connection.py +2 -13
  7. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/PKG-INFO +3 -8
  8. wrapture_instrumentation_postgresql-1.0.0.dev2/src/wrapture_instrumentation_postgresql.egg-info/requires.txt +1 -0
  9. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/test_recording.py +4 -11
  10. wrapture_instrumentation_postgresql-1.0.0.dev1/src/wrapture_instrumentation_postgresql.egg-info/requires.txt +0 -1
  11. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/CHANGES.md +0 -0
  12. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/Dockerfile +0 -0
  13. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/LICENSE +0 -0
  14. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/MANIFEST.in +0 -0
  15. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/TESTING.md +0 -0
  16. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/compose.yml +0 -0
  17. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/demo/__init__.py +0 -0
  18. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/demo/asyncpg.py +0 -0
  19. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/demo/psycopg.py +0 -0
  20. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/demo/psycopg2.py +0 -0
  21. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/setup.cfg +0 -0
  22. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/asyncpg/__init__.py +0 -0
  23. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/asyncpg/cursor.py +0 -0
  24. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/asyncpg/prepared.py +0 -0
  25. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/common.py +0 -0
  26. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg/README.md +0 -0
  27. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg/__init__.py +0 -0
  28. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg/connection.py +0 -0
  29. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg/cursor.py +0 -0
  30. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg/transaction.py +0 -0
  31. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg2/README.md +0 -0
  32. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg2/__init__.py +0 -0
  33. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/psycopg2/factories.py +0 -0
  34. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql/py.typed +0 -0
  35. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/SOURCES.txt +0 -0
  36. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/dependency_links.txt +0 -0
  37. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/entry_points.txt +0 -0
  38. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/not-zip-safe +0 -0
  39. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/src/wrapture_instrumentation_postgresql.egg-info/top_level.txt +0 -0
  40. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/__init__.py +0 -0
  41. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/__init__.py +0 -0
  42. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/conftest.py +0 -0
  43. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/test_apply_remove.py +0 -0
  44. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/test_class.py +0 -0
  45. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/test_composition.py +0 -0
  46. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/asyncpg/test_registration.py +0 -0
  47. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/conftest.py +0 -0
  48. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/__init__.py +0 -0
  49. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/conftest.py +0 -0
  50. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_apply_remove.py +0 -0
  51. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_async.py +0 -0
  52. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_class.py +0 -0
  53. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_composition.py +0 -0
  54. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_recording.py +0 -0
  55. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg/test_registration.py +0 -0
  56. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/__init__.py +0 -0
  57. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/conftest.py +0 -0
  58. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/test_apply_remove.py +0 -0
  59. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/test_class.py +0 -0
  60. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/test_composition.py +0 -0
  61. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/test_recording.py +0 -0
  62. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/psycopg2/test_registration.py +0 -0
  63. {wrapture_instrumentation_postgresql-1.0.0.dev1 → wrapture_instrumentation_postgresql-1.0.0.dev2}/tests/test_package.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wrapture-instrumentation-postgresql
3
- Version: 1.0.0.dev1
3
+ Version: 1.0.0.dev2
4
4
  Summary: Instrumentation for the PostgreSQL client libraries (psycopg, psycopg2, asyncpg), applied through wrapture.
5
5
  Author-email: Graham Dumpleton <Graham.Dumpleton@gmail.com>
6
6
  License-Expression: BSD-2-Clause
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Requires-Python: >=3.12
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
- Requires-Dist: wrapture>=1.0.0a20
21
+ Requires-Dist: wrapture>=1.0.0a21
22
22
  Dynamic: license-file
23
23
 
24
24
  # wrapture-instrumentation-postgresql
@@ -109,7 +109,7 @@ $ python -m wrapture.tools instrumentation --verbose
109
109
  | ------ | ------------------ | ------- | -------- |
110
110
  | [`psycopg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg/README.md) | psycopg 3.1+ (3.x) | Every query as one `database` leaf, however it was issued (a cursor's `execute` or `executemany`, the connection's shortcut, a streamed query, a COPY, a server-side cursor's DECLARE), plus the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager, and a `transaction()` block's begin and end, savepoints included); sync and async classes alike, and connections from a pool. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text is recorded only with the `statement` setting on, bound parameters never. | `statement` |
111
111
  | [`psycopg2`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg2/README.md) | psycopg2 2.9+ (2.x), psycopg2-binary alike | Every query as one `database` leaf, however it was issued (`execute`, `executemany`, `callproc`, the extras' batch helpers, a named cursor's DECLARE), each COPY (`copy_from`, `copy_to`, `copy_expert`), the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager); through recording subclasses injected by psycopg2's own factory mechanism, so your `cursor_factory` and `connection_factory` classes keep working and are recorded too. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (the template with its placeholders) is recorded only with the `statement` setting on, bound parameters never. | `statement` |
112
- | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool does not yet record its queries (a wrapture fix is pending). | `statement` |
112
+ | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool records its queries like any other. | `statement` |
113
113
 
114
114
  The entry point name is the config's `name`""; the linked per-target
115
115
  README is the full user documentation: what records, what the events
@@ -127,11 +127,6 @@ By design, and where it goes:
127
127
  records its queries like any other, but taking and returning it are
128
128
  not database operations and are not recorded.
129
129
 
130
- - A connection taken from an asyncpg pool does not yet record its
131
- queries: the pool proxy calls the connection's methods through the
132
- class, a calling convention wrapture's signature check does not
133
- yet handle. The fix is on wrapture's side.
134
-
135
130
  - LISTEN/NOTIFY, large objects and two-phase commit are out of scope.
136
131
 
137
132
  ## Adding a target
@@ -86,7 +86,7 @@ $ python -m wrapture.tools instrumentation --verbose
86
86
  | ------ | ------------------ | ------- | -------- |
87
87
  | [`psycopg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg/README.md) | psycopg 3.1+ (3.x) | Every query as one `database` leaf, however it was issued (a cursor's `execute` or `executemany`, the connection's shortcut, a streamed query, a COPY, a server-side cursor's DECLARE), plus the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager, and a `transaction()` block's begin and end, savepoints included); sync and async classes alike, and connections from a pool. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text is recorded only with the `statement` setting on, bound parameters never. | `statement` |
88
88
  | [`psycopg2`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg2/README.md) | psycopg2 2.9+ (2.x), psycopg2-binary alike | Every query as one `database` leaf, however it was issued (`execute`, `executemany`, `callproc`, the extras' batch helpers, a named cursor's DECLARE), each COPY (`copy_from`, `copy_to`, `copy_expert`), the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager); through recording subclasses injected by psycopg2's own factory mechanism, so your `cursor_factory` and `connection_factory` classes keep working and are recorded too. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (the template with its placeholders) is recorded only with the `statement` setting on, bound parameters never. | `statement` |
89
- | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool does not yet record its queries (a wrapture fix is pending). | `statement` |
89
+ | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool records its queries like any other. | `statement` |
90
90
 
91
91
  The entry point name is the config's `name`""; the linked per-target
92
92
  README is the full user documentation: what records, what the events
@@ -104,11 +104,6 @@ By design, and where it goes:
104
104
  records its queries like any other, but taking and returning it are
105
105
  not database operations and are not recorded.
106
106
 
107
- - A connection taken from an asyncpg pool does not yet record its
108
- queries: the pool proxy calls the connection's methods through the
109
- class, a calling convention wrapture's signature check does not
110
- yet handle. The fix is on wrapture's side.
111
-
112
107
  - LISTEN/NOTIFY, large objects and two-phase commit are out of scope.
113
108
 
114
109
  ## Adding a target
@@ -28,7 +28,7 @@ classifiers = [
28
28
  # install psycopg, and whether a driver is present and at a supported
29
29
  # version is checked by wrapture at apply time from the class data.
30
30
  dependencies = [
31
- "wrapture>=1.0.0a20",
31
+ "wrapture>=1.0.0a21",
32
32
  ]
33
33
 
34
34
  [project.urls]
@@ -22,5 +22,5 @@ def _format_version(parts: tuple[str, ...]) -> str:
22
22
  )
23
23
 
24
24
 
25
- __version_info__ = ("1", "0", "0", "dev1")
25
+ __version_info__ = ("1", "0", "0", "dev2")
26
26
  __version__ = _format_version(__version_info__)
@@ -90,7 +90,9 @@ asyncpg.prepared_stmt:PreparedStatement.fetchval(args='<1 values>', column=0, ti
90
90
  (`asyncpg.UndefinedTableError`, say) on the event as it escapes; a
91
91
  timeout or cancellation arrives the same way. A pool made after the
92
92
  instrumentation is applied opens its connections through the
93
- bound `connect`, on the task that awaited it, so those record too.
93
+ bound `connect`, on the task that awaited it, so those record too,
94
+ and a connection taken from the pool (`async with pool.acquire()
95
+ as conn:`) records its queries like one you opened yourself.
94
96
 
95
97
  ## Settings
96
98
 
@@ -118,16 +120,6 @@ prepared statement's own fetch, and the commit's `execute` beneath
118
120
  level either way, and the dialect's setup queries show up beside the
119
121
  tree regardless, since they run outside the recorded seams.
120
122
 
121
- ## Known gap
122
-
123
- A connection taken from a pool (`async with pool.acquire() as conn:`)
124
- does not yet record its queries: asyncpg's pool proxy calls the
125
- connection's methods through the class, `Connection.fetchval(
126
- connection, query)`, a calling convention wrapture's signature check
127
- does not yet handle. A fix is on wrapture's side and this note goes
128
- when it lands. The pool's connects record, and so does everything on
129
- a connection you opened yourself.
130
-
131
123
  ## How it patches
132
124
 
133
125
  For the implementation detail see the module docstrings of
@@ -167,19 +167,8 @@ def instrument(module: Any, instrumentation: wrapture.Instrumentation) -> None:
167
167
  wrapped: Any, instance: Any, args: tuple[Any, ...], kwargs: dict[str, Any]
168
168
  ) -> Any:
169
169
  async def record() -> Any:
170
- data = data_for(instance, query_of(args, kwargs), "COPY")
171
- wrapture.annotate(**data)
172
-
173
- # With arguments, asyncpg renders them into the query
174
- # through a SELECT on this same connection before the COPY:
175
- # a bound call beneath this leaf, silenced, whose own
176
- # annotation would otherwise leave the event saying
177
- # SELECT. The COPY's data is written again on the way out.
178
-
179
- try:
180
- return await wrapped(*args, **kwargs)
181
- finally:
182
- wrapture.annotate(**data)
170
+ wrapture.annotate(**data_for(instance, query_of(args, kwargs), "COPY"))
171
+ return await wrapped(*args, **kwargs)
183
172
 
184
173
  return record()
185
174
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wrapture-instrumentation-postgresql
3
- Version: 1.0.0.dev1
3
+ Version: 1.0.0.dev2
4
4
  Summary: Instrumentation for the PostgreSQL client libraries (psycopg, psycopg2, asyncpg), applied through wrapture.
5
5
  Author-email: Graham Dumpleton <Graham.Dumpleton@gmail.com>
6
6
  License-Expression: BSD-2-Clause
@@ -18,7 +18,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
18
18
  Requires-Python: >=3.12
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
- Requires-Dist: wrapture>=1.0.0a20
21
+ Requires-Dist: wrapture>=1.0.0a21
22
22
  Dynamic: license-file
23
23
 
24
24
  # wrapture-instrumentation-postgresql
@@ -109,7 +109,7 @@ $ python -m wrapture.tools instrumentation --verbose
109
109
  | ------ | ------------------ | ------- | -------- |
110
110
  | [`psycopg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg/README.md) | psycopg 3.1+ (3.x) | Every query as one `database` leaf, however it was issued (a cursor's `execute` or `executemany`, the connection's shortcut, a streamed query, a COPY, a server-side cursor's DECLARE), plus the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager, and a `transaction()` block's begin and end, savepoints included); sync and async classes alike, and connections from a pool. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text is recorded only with the `statement` setting on, bound parameters never. | `statement` |
111
111
  | [`psycopg2`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/psycopg2/README.md) | psycopg2 2.9+ (2.x), psycopg2-binary alike | Every query as one `database` leaf, however it was issued (`execute`, `executemany`, `callproc`, the extras' batch helpers, a named cursor's DECLARE), each COPY (`copy_from`, `copy_to`, `copy_expert`), the connection being opened and each transaction boundary (`commit`, `rollback`, the connection's context manager); through recording subclasses injected by psycopg2's own factory mechanism, so your `cursor_factory` and `connection_factory` classes keep working and are recorded too. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (the template with its placeholders) is recorded only with the `statement` setting on, bound parameters never. | `statement` |
112
- | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool does not yet record its queries (a wrapture fix is pending). | `statement` |
112
+ | [`asyncpg`](https://github.com/GrahamDumpleton/wrapture-instrumentation-postgresql/blob/develop/src/wrapture_instrumentation_postgresql/asyncpg/README.md) | asyncpg 0.29+ (0.x) | Every query as one `database` leaf recorded around its await, however it was issued (a connection's `execute`, `executemany`, `fetch`, `fetchrow`, `fetchval` or `fetchmany`, a prepared statement's own fetches, a server-side cursor's DECLARE and each FETCH), each COPY, the connection being opened, and each transaction boundary, which asyncpg issues through `execute`. Each event carries the system, the operation, and the database, host and port it reached; a failing statement records the driver's exception. The SQL text (with its `$n` placeholders) is recorded only with the `statement` setting on, query arguments never. A connection taken from a pool records its queries like any other. | `statement` |
113
113
 
114
114
  The entry point name is the config's `name`""; the linked per-target
115
115
  README is the full user documentation: what records, what the events
@@ -127,11 +127,6 @@ By design, and where it goes:
127
127
  records its queries like any other, but taking and returning it are
128
128
  not database operations and are not recorded.
129
129
 
130
- - A connection taken from an asyncpg pool does not yet record its
131
- queries: the pool proxy calls the connection's methods through the
132
- class, a calling convention wrapture's signature check does not
133
- yet handle. The fix is on wrapture's side.
134
-
135
130
  - LISTEN/NOTIFY, large objects and two-phase commit are out of scope.
136
131
 
137
132
  ## Adding a target
@@ -401,20 +401,13 @@ def test_a_pool_opens_its_connections_through_connect(
401
401
  contract(event, postgresql, "CONNECT")
402
402
 
403
403
 
404
- @pytest.mark.xfail(
405
- strict=True,
406
- reason=(
407
- "asyncpg's PoolConnectionProxy calls Connection's methods through the"
408
- " class, Connection.fetchval(connection, query), and wrapture's"
409
- " signature check binds the arguments against the unbound function,"
410
- " so the call is refused as missing its query; a wrapture fix is"
411
- " needed (resolve the signature with the instance already bound"
412
- " when wrapt hands over a partial)"
413
- ),
414
- )
415
404
  def test_a_pooled_connection_records_its_queries(
416
405
  postgresql: Server, tape: Tape
417
406
  ) -> None:
407
+ # asyncpg's pool proxy calls the connection's methods through the
408
+ # class, Connection.fetchval(connection, query); wrapture (on
409
+ # wrapt 2.4.1) binds that the same as the instance call.
410
+
418
411
  async def workload() -> int:
419
412
  pool = await asyncpg.create_pool(postgresql.url, min_size=1, max_size=1)
420
413
  try: