Skip to content

Commit 7808ecf

Browse files
authored
Add Werror to CI (#56277)
* Add Werror to CI * Add to build action * CircleCI Werror * Removed artificial failure * suppress float -> int cast warning * more warning suppression * macOS warning fixup * declaration fixup * more macOS fix * more macOS * even more macOS * more macOS * test casting precision
1 parent c08e7b3 commit 7808ecf

File tree

9 files changed

+40
-18
lines changed

9 files changed

+40
-18
lines changed

.circleci/setup_env.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,6 @@ if pip show pandas 1>/dev/null; then
5555
fi
5656

5757
echo "Install pandas"
58-
python -m pip install --no-build-isolation -ve .
58+
python -m pip install --no-build-isolation -ve . --config-settings=setup-args="--werror"
5959

6060
echo "done"

.github/actions/build_pandas/action.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ runs:
2525
- name: Build Pandas
2626
run: |
2727
if [[ ${{ inputs.editable }} == "true" ]]; then
28-
pip install -e . --no-build-isolation -v --no-deps
28+
pip install -e . --no-build-isolation -v --no-deps \
29+
--config-settings=setup-args="--werror"
2930
else
30-
pip install . --no-build-isolation -v --no-deps
31+
pip install . --no-build-isolation -v --no-deps \
32+
--config-settings=setup-args="--werror"
3133
fi
3234
shell: bash -el {0}

.github/workflows/unit-tests.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ jobs:
254254
python -m pip install --no-cache-dir -U pip wheel setuptools meson[ninja]==1.2.1 meson-python==0.13.1
255255
python -m pip install numpy --config-settings=setup-args="-Dallow-noblas=true"
256256
python -m pip install --no-cache-dir versioneer[toml] cython python-dateutil pytz pytest>=7.3.2 pytest-xdist>=2.2.0 hypothesis>=6.46.1
257-
python -m pip install --no-cache-dir --no-build-isolation -e .
257+
python -m pip install --no-cache-dir --no-build-isolation -e . --config-settings=setup-args="--werror"
258258
python -m pip list --no-cache-dir
259259
export PANDAS_CI=1
260260
python -m pytest -m 'not slow and not network and not clipboard and not single_cpu' pandas --junitxml=test-data.xml
@@ -292,7 +292,7 @@ jobs:
292292
. ~/virtualenvs/pandas-dev/bin/activate
293293
python -m pip install --no-cache-dir -U pip wheel setuptools meson-python==0.13.1 meson[ninja]==1.2.1
294294
python -m pip install --no-cache-dir versioneer[toml] cython numpy python-dateutil pytz pytest>=7.3.2 pytest-xdist>=2.2.0 hypothesis>=6.46.1
295-
python -m pip install --no-cache-dir --no-build-isolation -e .
295+
python -m pip install --no-cache-dir --no-build-isolation -e . --config-settings=setup-args="--werror"
296296
python -m pip list --no-cache-dir
297297
298298
- name: Run Tests
@@ -365,7 +365,7 @@ jobs:
365365
python -m pip install --pre --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy
366366
python -m pip install versioneer[toml]
367367
python -m pip install python-dateutil pytz tzdata cython hypothesis>=6.46.1 pytest>=7.3.2 pytest-xdist>=2.2.0 pytest-cov
368-
python -m pip install -ve . --no-build-isolation --no-index --no-deps
368+
python -m pip install -ve . --no-build-isolation --no-index --no-deps --config-settings=setup-args="--werror"
369369
python -m pip list
370370
371371
- name: Run Tests

pandas/_libs/include/pandas/datetime/date_conversions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The full license is in the LICENSE file, distributed with this software.
1212
#include <numpy/ndarraytypes.h>
1313

1414
// Scales value inplace from nanosecond resolution to unit resolution
15-
int scaleNanosecToUnit(npy_int64 *value, NPY_DATETIMEUNIT unit);
15+
int scaleNanosecToUnit(int64_t *value, NPY_DATETIMEUNIT unit);
1616

1717
// Converts an int64 object representing a date to ISO format
1818
// up to precision `base` e.g. base="s" yields 2020-01-03T00:00:00Z

pandas/_libs/include/pandas/datetime/pd_datetime.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern "C" {
3333
typedef struct {
3434
npy_datetime (*npy_datetimestruct_to_datetime)(NPY_DATETIMEUNIT,
3535
const npy_datetimestruct *);
36-
int (*scaleNanosecToUnit)(npy_int64 *, NPY_DATETIMEUNIT);
36+
int (*scaleNanosecToUnit)(int64_t *, NPY_DATETIMEUNIT);
3737
char *(*int64ToIso)(int64_t, NPY_DATETIMEUNIT, NPY_DATETIMEUNIT, size_t *);
3838
char *(*PyDateTimeToIso)(PyObject *, NPY_DATETIMEUNIT, size_t *);
3939
npy_datetime (*PyDateTimeToEpoch)(PyObject *, NPY_DATETIMEUNIT);

pandas/_libs/src/datetime/date_conversions.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The full license is in the LICENSE file, distributed with this software.
2020
*
2121
* Mutates the provided value directly. Returns 0 on success, non-zero on error.
2222
*/
23-
int scaleNanosecToUnit(npy_int64 *value, NPY_DATETIMEUNIT unit) {
23+
int scaleNanosecToUnit(int64_t *value, NPY_DATETIMEUNIT unit) {
2424
switch (unit) {
2525
case NPY_FR_ns:
2626
break;

pandas/_libs/src/datetime/pd_datetime.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static npy_datetime PyDateTimeToEpoch(PyObject *dt, NPY_DATETIMEUNIT base) {
176176
}
177177
}
178178

179-
npy_datetime npy_dt = npy_datetimestruct_to_datetime(NPY_FR_ns, &dts);
179+
int64_t npy_dt = npy_datetimestruct_to_datetime(NPY_FR_ns, &dts);
180180
if (scaleNanosecToUnit(&npy_dt, base) == -1) {
181181
PyErr_Format(PyExc_ValueError,
182182
"Call to scaleNanosecToUnit with value %" NPY_DATETIME_FMT

pandas/_libs/src/vendored/ujson/python/objToJSON.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -1235,11 +1235,11 @@ static char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
12351235
}
12361236

12371237
int is_datetimelike = 0;
1238-
npy_int64 i8date;
1238+
int64_t i8date;
12391239
NPY_DATETIMEUNIT dateUnit = NPY_FR_ns;
12401240
if (PyTypeNum_ISDATETIME(type_num)) {
12411241
is_datetimelike = 1;
1242-
i8date = *(npy_int64 *)dataptr;
1242+
i8date = *(int64_t *)dataptr;
12431243
dateUnit = get_datetime_metadata_from_dtype(dtype).base;
12441244
} else if (PyDate_Check(item) || PyDelta_Check(item)) {
12451245
is_datetimelike = 1;
@@ -1249,7 +1249,11 @@ static char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
12491249
i8date = get_long_attr(item, "_value");
12501250
} else {
12511251
if (PyDelta_Check(item)) {
1252-
i8date = total_seconds(item) * 1000000000LL; // nanoseconds per second
1252+
// TODO(anyone): cast below loses precision if total_seconds return
1253+
// value exceeds number of bits that significand can hold
1254+
// also liable to overflow
1255+
i8date = (int64_t)(total_seconds(item) *
1256+
1000000000LL); // nanoseconds per second
12531257
} else {
12541258
// datetime.* objects don't follow above rules
12551259
i8date = PyDateTimeToEpoch(item, NPY_FR_ns);
@@ -1290,7 +1294,7 @@ static char **NpyArr_encodeLabels(PyArrayObject *labels, PyObjectEncoder *enc,
12901294
ret = 0;
12911295
break;
12921296
}
1293-
snprintf(cLabel, size_of_cLabel, "%" NPY_DATETIME_FMT, i8date);
1297+
snprintf(cLabel, size_of_cLabel, "%" PRId64, i8date);
12941298
len = strlen(cLabel);
12951299
}
12961300
}
@@ -1494,10 +1498,14 @@ static void Object_beginTypeContext(JSOBJ _obj, JSONTypeContext *tc) {
14941498
}
14951499
return;
14961500
} else if (PyDelta_Check(obj)) {
1497-
npy_int64 value =
1498-
PyObject_HasAttrString(obj, "_value") ? get_long_attr(obj, "_value")
1499-
: // pd.Timedelta object or pd.NaT
1500-
total_seconds(obj) * 1000000000LL; // nanoseconds per sec
1501+
// pd.Timedelta object or pd.NaT should evaluate true here
1502+
// fallback to nanoseconds per sec for other objects
1503+
// TODO(anyone): cast below loses precision if total_seconds return
1504+
// value exceeds number of bits that significand can hold
1505+
// also liable to overflow
1506+
int64_t value = PyObject_HasAttrString(obj, "_value")
1507+
? get_long_attr(obj, "_value")
1508+
: (int64_t)(total_seconds(obj) * 1000000000LL);
15011509

15021510
if (value == get_nat()) {
15031511
tc->type = JT_NULL;

pandas/tests/io/json/test_pandas.py

+12
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,18 @@ def test_timedelta_to_json(self, as_object, date_format, timedelta_typ):
11471147
result = ser.to_json(date_format=date_format)
11481148
assert result == expected
11491149

1150+
@pytest.mark.parametrize("as_object", [True, False])
1151+
@pytest.mark.parametrize("timedelta_typ", [pd.Timedelta, timedelta])
1152+
def test_timedelta_to_json_fractional_precision(self, as_object, timedelta_typ):
1153+
data = [timedelta_typ(milliseconds=42)]
1154+
ser = Series(data, index=data)
1155+
if as_object:
1156+
ser = ser.astype(object)
1157+
1158+
result = ser.to_json()
1159+
expected = '{"42":42}'
1160+
assert result == expected
1161+
11501162
def test_default_handler(self):
11511163
value = object()
11521164
frame = DataFrame({"a": [7, value]})

0 commit comments

Comments
 (0)