@@ -49,32 +49,32 @@ typedef struct {
4949#include "clinic/compressor.c.h"
5050
5151static int
52- _zstd_set_c_level (ZstdCompressor * self , const Py_ssize_t level )
52+ _zstd_set_c_level (ZstdCompressor * self , const int level )
5353{
5454 /* Set integer compression level */
55- const int min_level = ZSTD_minCLevel ();
56- const int max_level = ZSTD_maxCLevel ();
55+ int min_level = ZSTD_minCLevel ();
56+ int max_level = ZSTD_maxCLevel ();
5757 if (level < min_level || level > max_level ) {
5858 PyErr_Format (PyExc_ValueError ,
59- "compression level %zd not in valid range %d <= level <= %d." ,
59+ " %zd not in valid range %d <= compression level <= %d." ,
6060 level , min_level , max_level );
6161 return -1 ;
6262 }
6363
6464 /* Save for generating ZSTD_CDICT */
65- self -> compression_level = ( int ) level ;
65+ self -> compression_level = level ;
6666
6767 /* Set compressionLevel to compression context */
68- const size_t zstd_ret = ZSTD_CCtx_setParameter (
69- self -> cctx , ZSTD_c_compressionLevel , ( int ) level );
68+ size_t zstd_ret = ZSTD_CCtx_setParameter (
69+ self -> cctx , ZSTD_c_compressionLevel , level );
7070
7171 /* Check error */
7272 if (ZSTD_isError (zstd_ret )) {
73- const _zstd_state * const st = PyType_GetModuleState (Py_TYPE (self ));
74- if (st == NULL ) {
73+ _zstd_state * mod_state = PyType_GetModuleState (Py_TYPE (self ));
74+ if (mod_state == NULL ) {
7575 return -1 ;
7676 }
77- set_zstd_error (st , ERR_SET_C_LEVEL , zstd_ret );
77+ set_zstd_error (mod_state , ERR_SET_C_LEVEL , zstd_ret );
7878 return -1 ;
7979 }
8080 return 0 ;
@@ -83,14 +83,14 @@ _zstd_set_c_level(ZstdCompressor *self, const Py_ssize_t level)
8383static int
8484_zstd_set_c_parameters (ZstdCompressor * self , PyObject * options )
8585{
86- /* Set options dict */
87- _zstd_state * const mod_state = PyType_GetModuleState (Py_TYPE (self ));
86+ _zstd_state * mod_state = PyType_GetModuleState (Py_TYPE (self ));
8887 if (mod_state == NULL ) {
8988 return -1 ;
9089 }
9190
9291 if (!PyDict_Check (options )) {
93- PyErr_Format (PyExc_TypeError , "invalid type for options, expected dict" );
92+ PyErr_Format (PyExc_TypeError ,
93+ "invalid type for options, expected dict" );
9494 return -1 ;
9595 }
9696
@@ -100,32 +100,38 @@ _zstd_set_c_parameters(ZstdCompressor *self, PyObject *options)
100100 /* Check key type */
101101 if (Py_TYPE (key ) == mod_state -> DParameter_type ) {
102102 PyErr_SetString (PyExc_TypeError ,
103- "key should NOT be DecompressionParameter." );
103+ "compression options dictionary key must not be a "
104+ "DecompressionParameter attribute" );
104105 return -1 ;
105106 }
106107
107- const int key_v = PyLong_AsInt (key );
108+ Py_INCREF (key );
109+ int key_v = PyLong_AsInt (key );
108110 if (key_v == -1 && PyErr_Occurred ()) {
109- PyErr_SetString (PyExc_ValueError ,
110- "key should be either a "
111- "CompressionParameter attribute or an int." );
111+ if (PyErr_ExceptionMatches (PyExc_OverflowError )) {
112+ PyErr_SetString (PyExc_ValueError ,
113+ "dictionary key must be less than 2**31" );
114+ }
112115 return -1 ;
113116 }
114117
115- // TODO(emmatyping): check bounds when there is a value error here for better
116- // error message?
118+ Py_INCREF (value );
117119 int value_v = PyLong_AsInt (value );
118120 if (value_v == -1 && PyErr_Occurred ()) {
119- PyErr_SetString (PyExc_ValueError ,
120- "options dict value should be an int." );
121+ if (PyErr_ExceptionMatches (PyExc_OverflowError )) {
122+ PyErr_SetString (PyExc_ValueError ,
123+ "dictionary value must be less than 2**31" );
124+ }
121125 return -1 ;
122126 }
123127
124128 if (key_v == ZSTD_c_compressionLevel ) {
125- /* Save for generating ZSTD_CDICT */
126- self -> compression_level = value_v ;
129+ if (_zstd_set_c_level (self , value_v ) < 0 ) {
130+ return -1 ;
131+ }
132+ continue ;
127133 }
128- else if (key_v == ZSTD_c_nbWorkers ) {
134+ if (key_v == ZSTD_c_nbWorkers ) {
129135 /* From the zstd library docs:
130136 1. When nbWorkers >= 1, triggers asynchronous mode when
131137 used with ZSTD_compressStream2().
@@ -138,7 +144,7 @@ _zstd_set_c_parameters(ZstdCompressor *self, PyObject *options)
138144 }
139145
140146 /* Set parameter to compression context */
141- const size_t zstd_ret = ZSTD_CCtx_setParameter (self -> cctx , key_v , value_v );
147+ size_t zstd_ret = ZSTD_CCtx_setParameter (self -> cctx , key_v , value_v );
142148 if (ZSTD_isError (zstd_ret )) {
143149 set_parameter_error (mod_state , 1 , key_v , value_v );
144150 return -1 ;
@@ -323,7 +329,7 @@ _zstd_load_c_dict(ZstdCompressor *self, PyObject *dict)
323329/*[clinic input]
324330@classmethod
325331_zstd.ZstdCompressor.__new__ as _zstd_ZstdCompressor_new
326- level: Py_ssize_t(c_default='PY_SSIZE_T_MIN', accept={int, NoneType}) = None
332+ level: object = None
327333 The compression level to use. Defaults to COMPRESSION_LEVEL_DEFAULT.
328334 options: object = None
329335 A dict object that contains advanced compression parameters.
@@ -337,9 +343,9 @@ function instead.
337343[clinic start generated code]*/
338344
339345static PyObject *
340- _zstd_ZstdCompressor_new_impl (PyTypeObject * type , Py_ssize_t level ,
346+ _zstd_ZstdCompressor_new_impl (PyTypeObject * type , PyObject * level ,
341347 PyObject * options , PyObject * zstd_dict )
342- /*[clinic end generated code: output=a857ec0dc29fc5e2 input=9899740b24d11319 ]*/
348+ /*[clinic end generated code: output=cdef61eafecac3d7 input=92de0211ae20ffdc ]*/
343349{
344350 ZstdCompressor * self = PyObject_GC_New (ZstdCompressor , type );
345351 if (self == NULL ) {
@@ -364,19 +370,34 @@ _zstd_ZstdCompressor_new_impl(PyTypeObject *type, Py_ssize_t level,
364370 /* Last mode */
365371 self -> last_mode = ZSTD_e_end ;
366372
367- if (level != PY_SSIZE_T_MIN && options != Py_None ) {
373+ if (level != Py_None && options != Py_None ) {
368374 PyErr_SetString (PyExc_RuntimeError ,
369375 "Only one of level or options should be used." );
370376 goto error ;
371377 }
372378
373- /* Set compressLevel/options to compression context */
374- if (level != PY_SSIZE_T_MIN ) {
375- if (_zstd_set_c_level (self , level ) < 0 ) {
379+ /* Set compression level */
380+ if (level != Py_None ) {
381+ if (!PyLong_Check (level )) {
382+ PyErr_SetString (PyExc_TypeError ,
383+ "invalid type for level, expected int" );
384+ goto error ;
385+ }
386+ int level_v = PyLong_AsInt (level );
387+ if (level_v == -1 && PyErr_Occurred ()) {
388+ if (PyErr_ExceptionMatches (PyExc_OverflowError )) {
389+ PyErr_Format (PyExc_ValueError ,
390+ "%zd not in valid range %d <= compression level <= %d." ,
391+ level , ZSTD_minCLevel (), ZSTD_maxCLevel ());
392+ }
393+ goto error ;
394+ }
395+ if (_zstd_set_c_level (self , level_v ) < 0 ) {
376396 goto error ;
377397 }
378398 }
379399
400+ /* Set options dictionary */
380401 if (options != Py_None ) {
381402 if (_zstd_set_c_parameters (self , options ) < 0 ) {
382403 goto error ;
@@ -693,6 +714,8 @@ PyDoc_STRVAR(ZstdCompressor_last_mode_doc,
693714static PyMemberDef ZstdCompressor_members [] = {
694715 {"last_mode" , Py_T_INT , offsetof(ZstdCompressor , last_mode ),
695716 Py_READONLY , ZstdCompressor_last_mode_doc },
717+ {"compression_level" , Py_T_INT , offsetof(ZstdCompressor , compression_level ),
718+ Py_READONLY , NULL },
696719 {NULL }
697720};
698721
0 commit comments