@descryy/runtime-adapter-python 0.4.5 → 0.4.7
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.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/python-frame-parsing.d.ts +1 -0
- package/dist/python-frame-parsing.d.ts.map +1 -1
- package/dist/python-frame-parsing.js +5 -1
- package/dist/python-frame-parsing.js.map +1 -1
- package/package.json +10 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { RawPythonFrame } from "./python-frame-parsing.ts";
|
|
2
|
-
export { CHAINED_EXCEPTION_CONNECTIVES, createPythonLineClassifier, isPythonBannerLine, isPythonLocationLine, isPythonTrailerLine, looksLikeContinuation, parsePythonFrame, } from "./python-frame-parsing.ts";
|
|
2
|
+
export { CHAINED_EXCEPTION_CONNECTIVES, createPythonLineClassifier, isPythonBannerLine, isPythonLocationLine, isPythonTrailerLine, isPythonRepeatedFrameLine, looksLikeContinuation, parsePythonFrame, } from "./python-frame-parsing.ts";
|
|
3
3
|
export { createUvicornLogEnvelope, pythonLogPatternRegistry, UVICORN_LOG_PATTERN } from "./python-log-envelopes.ts";
|
|
4
4
|
export { createPythonSourceLocationResolver } from "./python-source-location-resolver.ts";
|
|
5
5
|
export { createPythonStackTraceParser } from "./python-stack-trace-parser.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,YAAY,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,YAAY,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CHAINED_EXCEPTION_CONNECTIVES, createPythonLineClassifier, isPythonBannerLine, isPythonLocationLine, isPythonTrailerLine, looksLikeContinuation, parsePythonFrame, } from "./python-frame-parsing.js";
|
|
1
|
+
export { CHAINED_EXCEPTION_CONNECTIVES, createPythonLineClassifier, isPythonBannerLine, isPythonLocationLine, isPythonTrailerLine, isPythonRepeatedFrameLine, looksLikeContinuation, parsePythonFrame, } from "./python-frame-parsing.js";
|
|
2
2
|
export { createUvicornLogEnvelope, pythonLogPatternRegistry, UVICORN_LOG_PATTERN } from "./python-log-envelopes.js";
|
|
3
3
|
export { createPythonSourceLocationResolver } from "./python-source-location-resolver.js";
|
|
4
4
|
export { createPythonStackTraceParser } from "./python-stack-trace-parser.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpH,OAAO,EAAE,kCAAkC,EAAE,MAAM,sCAAsC,CAAC;AAC1F,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAE9E,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,gCAAgC,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
@@ -38,6 +38,7 @@ export declare function isPythonLocationLine(line: string): boolean;
|
|
|
38
38
|
* See `createPythonLineClassifier`, which is what the adapter actually uses.
|
|
39
39
|
*/
|
|
40
40
|
export declare function looksLikeContinuation(line: string): boolean;
|
|
41
|
+
export declare function isPythonRepeatedFrameLine(line: string): boolean;
|
|
41
42
|
export declare function isPythonTrailerLine(line: string): boolean;
|
|
42
43
|
/**
|
|
43
44
|
* Stateful, and the statefulness is the point. The obvious stateless rule —
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-frame-parsing.d.ts","sourceRoot":"","sources":["../src/python-frame-parsing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,cAAc;IAC7B,iHAAiH;IACjH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA0BD,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;
|
|
1
|
+
{"version":3,"file":"python-frame-parsing.d.ts","sourceRoot":"","sources":["../src/python-frame-parsing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,cAAc;IAC7B,iHAAiH;IACjH,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,0GAA0G;IAC1G,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AA0BD,0FAA0F;AAC1F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAiDD;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,0JAGhC,CAAC;AAEX,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,IAAI;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAClC,CA8BA;AAED,yGAAyG;AACzG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAOpE"}
|
|
@@ -55,6 +55,7 @@ const FILE_LINE_LOOSE_PATTERN = /^\s*File "(?<file>.*)"/;
|
|
|
55
55
|
* trailer (`ValueError: ...`) is never read as one.
|
|
56
56
|
*/
|
|
57
57
|
const CONTINUATION_PATTERN = /^\s{3,}\S/;
|
|
58
|
+
const REPEATED_FRAME_PATTERN = /^\s*\[Previous line repeated \d+ more times?\]\s*$/;
|
|
58
59
|
/**
|
|
59
60
|
* The closing line: `ValueError: bad input`, a dotted `myapp.errors.ConfigError:
|
|
60
61
|
* ...`, or a bare `SystemExit`. Anchored at zero indent — every frame line is indented.
|
|
@@ -106,6 +107,9 @@ export function isPythonLocationLine(line) {
|
|
|
106
107
|
export function looksLikeContinuation(line) {
|
|
107
108
|
return CONTINUATION_PATTERN.test(stripExceptionGroupGutter(line));
|
|
108
109
|
}
|
|
110
|
+
export function isPythonRepeatedFrameLine(line) {
|
|
111
|
+
return REPEATED_FRAME_PATTERN.test(stripExceptionGroupGutter(line));
|
|
112
|
+
}
|
|
109
113
|
export function isPythonTrailerLine(line) {
|
|
110
114
|
if (CHAINED_EXCEPTION_CONNECTIVES.some((c) => line.trim() === c))
|
|
111
115
|
return false;
|
|
@@ -140,7 +144,7 @@ export function createPythonLineClassifier() {
|
|
|
140
144
|
sawLocationLine = true;
|
|
141
145
|
return true;
|
|
142
146
|
}
|
|
143
|
-
if (sawLocationLine && looksLikeContinuation(line))
|
|
147
|
+
if (sawLocationLine && (looksLikeContinuation(line) || isPythonRepeatedFrameLine(line)))
|
|
144
148
|
return true;
|
|
145
149
|
sawLocationLine = false;
|
|
146
150
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-frame-parsing.js","sourceRoot":"","sources":["../src/python-frame-parsing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAUH,MAAM,cAAc,GAAG,sCAAsC,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEzC,0FAA0F;AAC1F,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC;AAED;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,kEAAkE,CAAC;AAC7F,MAAM,uBAAuB,GAAG,wBAAwB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,oBAAoB,GAAG,WAAW,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,eAAe,GAAG,+CAA+C,CAAC;AAExE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,qEAAqE;IACrE,sEAAsE;CAC9D,CAAC;AAEX,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,uBAAuB,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,oBAAoB,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,6BAA6B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,OAAO,eAAe,CAAC,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,0BAA0B;IAKxC,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,OAAO;QACL,QAAQ,CAAC,IAAY;YACnB,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,eAAe,GAAG,KAAK,CAAC;gBACxB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,CAAC,IAAY;YAClB,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,eAAe,GAAG,IAAI,CAAC;gBACvB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,eAAe,IAAI,qBAAqB,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"python-frame-parsing.js","sourceRoot":"","sources":["../src/python-frame-parsing.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descryy/runtime-adapter-python",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Python runtime adapter: CPython traceback parsing, self-contained source locations, outbound httpx call-site instrumentation, the concrete RuntimeAdapter for Python.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -26,11 +26,15 @@
|
|
|
26
26
|
"registry": "https://registry.npmjs.org",
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@descryy/runtime-contracts": "0.4.1",
|
|
31
|
+
"@descryy/runtime-backend-observation": "0.3.8"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@descryy/runtime-controller": "0.4.1",
|
|
35
|
+
"@descryy/runtime-external-service-observation": "0.3.7"
|
|
36
|
+
},
|
|
29
37
|
"scripts": {
|
|
30
38
|
"build": "tsc -b"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@descryy/runtime-contracts": "0.3.3",
|
|
34
|
-
"@descryy/runtime-backend-observation": "0.3.6"
|
|
35
39
|
}
|
|
36
|
-
}
|
|
40
|
+
}
|