Skip to content

Commit 2317589

Browse files
eustascopybara-github
authored andcommitted
use module-bound exception
PiperOrigin-RevId: 811366325
1 parent 1406898 commit 2317589

File tree

1 file changed

+51
-29
lines changed

1 file changed

+51
-29
lines changed

python/_brotli.c

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#define PY_GET_TYPE(Obj) ((Obj)->ob_type)
1919
#endif
2020

21-
static PyObject* BrotliError;
21+
static const char kErrorAttr[] = "error";
22+
static const char kModuleAttr[] = "_module";
2223

2324
static const char kInvalidBufferError[] =
2425
"brotli: data must be a C-contiguous buffer";
@@ -195,8 +196,26 @@ PyDoc_STRVAR(brotli_doc,
195196
"Implementation module for the Brotli library.");
196197
/* clang-format on */
197198

198-
static void set_brotli_exception(const char* msg) {
199-
PyErr_SetString(BrotliError, msg);
199+
static void set_brotli_exception(PyObject* context, const char* msg) {
200+
assert(context != NULL);
201+
PyObject* module = NULL;
202+
PyObject* type = NULL;
203+
PyObject* error = NULL;
204+
if (PyModule_Check(context)) {
205+
module = context;
206+
} else if (PyType_Check(context)) {
207+
type = context;
208+
} else {
209+
type = (PyObject*)PY_GET_TYPE(context);
210+
assert(type != NULL);
211+
}
212+
if (type) {
213+
module = PyObject_GetAttrString(type, kModuleAttr);
214+
}
215+
assert(module != NULL);
216+
error = PyObject_GetAttrString(module, kErrorAttr);
217+
assert(error != NULL);
218+
PyErr_SetString(error, msg);
200219
}
201220

202221
/*
@@ -354,7 +373,7 @@ static PyObject* brotli_Compressor_new(PyTypeObject* type, PyObject* args,
354373
self->processing = 0;
355374
self->enc = BrotliEncoderCreateInstance(0, 0, 0);
356375
if (self->enc == NULL) {
357-
set_brotli_exception(kCompressCreateError);
376+
set_brotli_exception((PyObject*)type, kCompressCreateError);
358377
PY_GET_TYPE(self)->tp_free((PyObject*)self);
359378
return NULL;
360379
}
@@ -386,30 +405,30 @@ static int brotli_Compressor_init(PyBrotli_Compressor* self, PyObject* args,
386405
if ((mode == 0) || (mode == 1) || (mode == 2)) {
387406
BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_MODE, (uint32_t)mode);
388407
} else {
389-
set_brotli_exception(kInvalidModeError);
408+
set_brotli_exception((PyObject*)self, kInvalidModeError);
390409
self->healthy = 0;
391410
return -1;
392411
}
393412
if (quality <= 11) {
394413
BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_QUALITY,
395414
(uint32_t)quality);
396415
} else {
397-
set_brotli_exception(kInvalidQualityError);
416+
set_brotli_exception((PyObject*)self, kInvalidQualityError);
398417
self->healthy = 0;
399418
return -1;
400419
}
401420
if ((10 <= lgwin) && (lgwin <= 24)) {
402421
BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGWIN, (uint32_t)lgwin);
403422
} else {
404-
set_brotli_exception(kInvalidLgwinError);
423+
set_brotli_exception((PyObject*)self, kInvalidLgwinError);
405424
self->healthy = 0;
406425
return -1;
407426
}
408427
if ((lgblock == 0) || ((16 <= lgblock) && (lgblock <= 24))) {
409428
BrotliEncoderSetParameter(self->enc, BROTLI_PARAM_LGBLOCK,
410429
(uint32_t)lgblock);
411430
} else {
412-
set_brotli_exception(kInvalidLgblockError);
431+
set_brotli_exception((PyObject*)self, kInvalidLgblockError);
413432
self->healthy = 0;
414433
return -1;
415434
}
@@ -471,7 +490,7 @@ static PyObject* compress_stream(PyBrotli_Compressor* self,
471490
ret = Buffer_Finish(&buffer);
472491
if (ret == NULL) oom = 1;
473492
} else { /* Not ok */
474-
set_brotli_exception(kCompressError);
493+
set_brotli_exception((PyObject*)self, kCompressError);
475494
}
476495

477496
error:
@@ -495,11 +514,11 @@ static PyObject* brotli_Compressor_process(PyBrotli_Compressor* self,
495514
Py_buffer input;
496515

497516
if (self->healthy == 0) {
498-
set_brotli_exception(kCompressUnhealthyError);
517+
set_brotli_exception((PyObject*)self, kCompressUnhealthyError);
499518
return NULL;
500519
}
501520
if (self->processing != 0) {
502-
set_brotli_exception(kCompressConcurrentError);
521+
set_brotli_exception((PyObject*)self, kCompressConcurrentError);
503522
return NULL;
504523
}
505524

@@ -522,11 +541,11 @@ static PyObject* brotli_Compressor_flush(PyBrotli_Compressor* self) {
522541
PyObject* ret = NULL;
523542

524543
if (self->healthy == 0) {
525-
set_brotli_exception(kCompressUnhealthyError);
544+
set_brotli_exception((PyObject*)self, kCompressUnhealthyError);
526545
return NULL;
527546
}
528547
if (self->processing != 0) {
529-
set_brotli_exception(kCompressConcurrentError);
548+
set_brotli_exception((PyObject*)self, kCompressConcurrentError);
530549
return NULL;
531550
}
532551

@@ -540,11 +559,11 @@ static PyObject* brotli_Compressor_finish(PyBrotli_Compressor* self) {
540559
PyObject* ret = NULL;
541560

542561
if (self->healthy == 0) {
543-
set_brotli_exception(kCompressUnhealthyError);
562+
set_brotli_exception((PyObject*)self, kCompressUnhealthyError);
544563
return NULL;
545564
}
546565
if (self->processing != 0) {
547-
set_brotli_exception(kCompressConcurrentError);
566+
set_brotli_exception((PyObject*)self, kCompressConcurrentError);
548567
return NULL;
549568
}
550569

@@ -578,7 +597,7 @@ static PyObject* brotli_Decompressor_new(PyTypeObject* type, PyObject* args,
578597

579598
self->dec = BrotliDecoderCreateInstance(0, 0, 0);
580599
if (self->dec == NULL) {
581-
set_brotli_exception(kDecompressCreateError);
600+
set_brotli_exception((PyObject*)type, kDecompressCreateError);
582601
PY_GET_TYPE(self)->tp_free((PyObject*)self);
583602
return NULL;
584603
}
@@ -633,11 +652,11 @@ static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
633652
int oom = 0;
634653

635654
if (self->healthy == 0) {
636-
set_brotli_exception(kDecompressUnhealthyError);
655+
set_brotli_exception((PyObject*)self, kDecompressUnhealthyError);
637656
return NULL;
638657
}
639658
if (self->processing != 0) {
640-
set_brotli_exception(kDecompressConcurrentError);
659+
set_brotli_exception((PyObject*)self, kDecompressConcurrentError);
641660
return NULL;
642661
}
643662

@@ -654,7 +673,7 @@ static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
654673

655674
if (self->unconsumed_data_length > 0) {
656675
if (input.len > 0) {
657-
set_brotli_exception(kDecompressSinkError);
676+
set_brotli_exception((PyObject*)self, kDecompressSinkError);
658677
goto finally;
659678
}
660679
next_in = self->unconsumed_data;
@@ -693,7 +712,7 @@ static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
693712
if (oom) {
694713
goto finally;
695714
} else if (result == BROTLI_DECODER_RESULT_ERROR) {
696-
set_brotli_exception(kDecompressError);
715+
set_brotli_exception((PyObject*)self, kDecompressError);
697716
goto finally;
698717
}
699718

@@ -712,7 +731,7 @@ static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
712731

713732
if ((result == BROTLI_DECODER_RESULT_SUCCESS) && (avail_in > 0)) {
714733
/* TODO(eustas): Add API to ignore / fetch unused "tail"? */
715-
set_brotli_exception(kDecompressError);
734+
set_brotli_exception((PyObject*)self, kDecompressError);
716735
goto finally;
717736
}
718737

@@ -742,11 +761,11 @@ static PyObject* brotli_Decompressor_process(PyBrotli_Decompressor* self,
742761

743762
static PyObject* brotli_Decompressor_is_finished(PyBrotli_Decompressor* self) {
744763
if (self->healthy == 0) {
745-
set_brotli_exception(kDecompressUnhealthyError);
764+
set_brotli_exception((PyObject*)self, kDecompressUnhealthyError);
746765
return NULL;
747766
}
748767
if (self->processing != 0) {
749-
set_brotli_exception(kDecompressConcurrentError);
768+
set_brotli_exception((PyObject*)self, kDecompressConcurrentError);
750769
return NULL;
751770
}
752771
if (BrotliDecoderIsFinished(self->dec)) {
@@ -759,11 +778,11 @@ static PyObject* brotli_Decompressor_is_finished(PyBrotli_Decompressor* self) {
759778
static PyObject* brotli_Decompressor_can_accept_more_data(
760779
PyBrotli_Decompressor* self) {
761780
if (self->healthy == 0) {
762-
set_brotli_exception(kDecompressUnhealthyError);
781+
set_brotli_exception((PyObject*)self, kDecompressUnhealthyError);
763782
return NULL;
764783
}
765784
if (self->processing != 0) {
766-
set_brotli_exception(kDecompressConcurrentError);
785+
set_brotli_exception((PyObject*)self, kDecompressConcurrentError);
767786
return NULL;
768787
}
769788
if (self->unconsumed_data_length > 0) {
@@ -832,7 +851,7 @@ static PyObject* brotli_decompress(PyObject* self, PyObject* args,
832851
if (oom) {
833852
goto finally;
834853
} else if (result != BROTLI_DECODER_RESULT_SUCCESS || available_in > 0) {
835-
set_brotli_exception(kDecompressError);
854+
set_brotli_exception((PyObject*)self, kDecompressError);
836855
goto finally;
837856
}
838857

@@ -1032,16 +1051,15 @@ PyMODINIT_FUNC INIT_BROTLI(void) {
10321051
PyObject* error_type = NULL;
10331052
PyObject* compressor_type = NULL;
10341053
PyObject* decompressor_type = NULL;
1054+
PyObject* obj = NULL; /* Dangling ref, don't deref this one. */
10351055

10361056
if (m == NULL) goto error;
10371057

10381058
error_type = PyErr_NewExceptionWithDoc((char*)"brotli.error",
10391059
brotli_error_doc, NULL, NULL);
10401060
if (error_type == NULL) goto error;
10411061

1042-
if (RegisterObject(m, "error", error_type) < 0) goto error;
1043-
/* Assumption: pointer is used only while module is alive and well. */
1044-
BrotliError = error_type;
1062+
if (RegisterObject(m, kErrorAttr, error_type) < 0) goto error;
10451063
error_type = NULL;
10461064

10471065
#if PY_MAJOR_VERSION >= 3
@@ -1056,12 +1074,16 @@ PyMODINIT_FUNC INIT_BROTLI(void) {
10561074
if (compressor_type == NULL) goto error;
10571075
if (PyType_Ready((PyTypeObject*)compressor_type) < 0) goto error;
10581076
if (RegisterObject(m, "Compressor", compressor_type) < 0) goto error;
1077+
obj = compressor_type;
10591078
compressor_type = NULL;
1079+
if (PyObject_SetAttrString(obj, kModuleAttr, m) < 0) goto error;
10601080

10611081
if (decompressor_type == NULL) goto error;
10621082
if (PyType_Ready((PyTypeObject*)decompressor_type) < 0) goto error;
10631083
if (RegisterObject(m, "Decompressor", decompressor_type) < 0) goto error;
1084+
obj = decompressor_type;
10641085
decompressor_type = NULL;
1086+
if (PyObject_SetAttrString(obj, kModuleAttr, m) < 0) goto error;
10651087

10661088
PyModule_AddIntConstant(m, "MODE_GENERIC", (int)BROTLI_MODE_GENERIC);
10671089
PyModule_AddIntConstant(m, "MODE_TEXT", (int)BROTLI_MODE_TEXT);

0 commit comments

Comments
 (0)