[med-svn] [Git][med-team/patsy][master] 7 commits: New upstream version 1.0.2
Nilesh Patra (@nilesh)
gitlab at salsa.debian.org
Sat Oct 25 11:12:54 BST 2025
Nilesh Patra pushed to branch master at Debian Med / patsy
Commits:
e40f1ec5 by Nilesh Patra at 2025-10-25T15:33:56+05:30
New upstream version 1.0.2
- - - - -
e0e127ab by Nilesh Patra at 2025-10-25T15:33:57+05:30
Update upstream source from tag 'upstream/1.0.2'
Update to upstream version '1.0.2'
with Debian dir 95a20e21bce625565960bb8e8b517698b63da10a
- - - - -
4c488a1e by Nilesh Patra at 2025-10-25T15:34:18+05:30
Drop myself from uploaders
- - - - -
471d81af by Nilesh Patra at 2025-10-25T15:34:26+05:30
Bump Standards-Version to 4.7.2 (no changes needed)
- - - - -
368fa407 by Nilesh Patra at 2025-10-25T15:34:54+05:30
Drop Redundant "Rules-Requires-Root: no"
- - - - -
04306ad0 by Nilesh Patra at 2025-10-25T15:37:16+05:30
Re-diff patches
- - - - -
381ad3af by Nilesh Patra at 2025-10-25T15:37:16+05:30
Upload to unstable
- - - - -
24 changed files:
- − .github/workflows/publish.yml
- − .github/workflows/tox.yml
- .pre-commit-config.yaml
- README.md
- debian/changelog
- debian/control
- debian/patches/Remove-external-image-links.patch
- doc/changes.rst
- patsy/build.py
- patsy/categorical.py
- patsy/constraint.py
- patsy/desc.py
- patsy/design_info.py
- patsy/eval.py
- patsy/highlevel.py
- patsy/mgcv_cubic_splines.py
- patsy/missing.py
- patsy/parse_formula.py
- patsy/splines.py
- patsy/test_highlevel.py
- patsy/tokens.py
- patsy/util.py
- patsy/version.py
- tox.ini
Changes:
=====================================
.github/workflows/publish.yml deleted
=====================================
@@ -1,27 +0,0 @@
-name: Publish tagged releases to PyPI
-
-on:
- push:
- tags:
- - "v*"
-
-jobs:
- deploy:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout at v1
- - name: Set up Python
- uses: actions/setup-python at v1
- with:
- python-version: '3.7'
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install setuptools wheel twine
- - name: Build and publish
- env:
- TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
- TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
- run: |
- python setup.py sdist bdist_wheel
- twine upload dist/*
=====================================
.github/workflows/tox.yml deleted
=====================================
@@ -1,57 +0,0 @@
-name: Run Tox Tests
-
-on:
- push:
- branches:
- - "*"
- pull_request:
- branches:
- - "*"
-
-jobs:
- build:
- runs-on: ubuntu-latest
- strategy:
- max-parallel: 4
- matrix:
- python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
- pandas-presence: ['with_pandas', 'without_pandas']
- env:
- PYTHON_VERSION: ${{ matrix.python-version }}
- PANDAS_PRESENCE: ${{ matrix.pandas-presence }}
- steps:
- - uses: actions/checkout at v2
- - name: Set up Python ${{ matrix.python-version }}
- id: gha-python
- uses: actions/setup-python at v4
- with:
- python-version: ${{ matrix.python-version }}
- continue-on-error: true
- - name: Install PyEnv
- if: ${{ steps.gha-python.outcome == 'failure' }}
- run: |
- curl https://pyenv.run | bash
- PYENV_ROOT="$HOME/.pyenv"
- echo "$PYENV_ROOT/bin" >> $GITHUB_PATH
- echo "$PYENV_ROOT/shims" >> $GITHUB_PATH
- echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
- - name: Install Python ${{ matrix.python-version }} using PyEnv
- if: ${{ steps.gha-python.outcome == 'failure' }}
- run: |
- pyenv install "${{ matrix.python-version }}"
- pyenv local "${{ matrix.python-version }}"
- pyenv versions
- - name: Install dependencies
- run: |
- pip install -U pip
- pip install tox tox-gh-actions
- - name: Test with tox
- run: |
- PYTHON_ENV="py$(echo $PYTHON_VERSION | sed 's/\.//;s/\-dev//')"
- tox -e "${PYTHON_ENV}-${PANDAS_PRESENCE}"
- - name: Upload coverage to Codecov
- uses: codecov/codecov-action at v1.0.10
- with:
- file: ./coverage.xml
- flags: unittests
- env_vars: PYTHON_VERSION,PANDAS_PRESENCE
=====================================
.pre-commit-config.yaml
=====================================
@@ -1,14 +1,12 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v5.0.0
+ rev: v6.0.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: fix-byte-order-marker
- id: destroyed-symlinks
- - id: fix-encoding-pragma
- args: ["--remove"]
- id: mixed-line-ending
- id: name-tests-test
args: ["--pytest-test-first"]
@@ -17,7 +15,7 @@ repos:
exclude: ".ipynb"
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.7.3
+ rev: v0.13.2
hooks:
- id: ruff-format
types_or: [ python, pyi, jupyter ]
=====================================
README.md
=====================================
@@ -20,7 +20,7 @@ building design matrices. Patsy brings the convenience of [R](http://www.r-proje



-
+[](https://coveralls.io/github/pydata/patsy)

- **Documentation:** <https://patsy.readthedocs.io/>
=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+patsy (1.0.2-1) unstable; urgency=medium
+
+ * Team Upload.
+ * New upstream version 1.0.2
+ * Drop myself from uploaders
+ * Bump Standards-Version to 4.7.2 (no changes needed)
+ * Drop Redundant "Rules-Requires-Root: no"
+
+ -- Nilesh Patra <nilesh at debian.org> Sat, 25 Oct 2025 15:35:36 +0530
+
patsy (1.0.1-1) unstable; urgency=medium
* Team upload.
=====================================
debian/control
=====================================
@@ -2,7 +2,6 @@ Source: patsy
Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
Uploaders: Yaroslav Halchenko <debian at onerussian.com>,
Michael Hanke <michael.hanke at gmail.com>,
- Nilesh Patra <nilesh at debian.org>
Section: python
Priority: optional
Build-Depends: debhelper-compat (= 13),
@@ -17,12 +16,11 @@ Build-Depends: debhelper-compat (= 13),
python3-matplotlib,
python3-sphinx,
ipython3,
-Standards-Version: 4.6.2
+Standards-Version: 4.7.2
Testsuite: autopkgtest-pkg-pybuild
Vcs-Browser: https://salsa.debian.org/med-team/patsy
Vcs-Git: https://salsa.debian.org/med-team/patsy.git
Homepage: https://github.com/pydata/patsy
-Rules-Requires-Root: no
Package: python3-patsy
Architecture: all
=====================================
debian/patches/Remove-external-image-links.patch
=====================================
@@ -14,5 +14,5 @@ Last Changed: Sat, July 11, 2020
- :target: https://doi.org/10.5281/zenodo.592075
+All Patsy releases are archived at Zenodo.
- v1.0.1
+ v1.0.2
------
=====================================
doc/changes.rst
=====================================
@@ -8,6 +8,11 @@ All Patsy releases are archived at Zenodo:
.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.592075.svg
:target: https://doi.org/10.5281/zenodo.592075
+v1.0.2
+------
+
+* Fixed compatibility with Pandas 3's new `StringDtype`.
+
v1.0.1
------
=====================================
patsy/build.py
=====================================
@@ -285,7 +285,7 @@ def _build_subterm(subterm, factor_infos, factor_values, out):
contrast = subterm.contrast_matrices[factor]
if np.any(factor_values[factor] < 0):
raise PatsyError(
- "can't build a design matrix " "containing missing values",
+ "can't build a design matrix containing missing values",
factor,
)
out[:, i] *= contrast.matrix[factor_values[factor], column_idx]
@@ -929,9 +929,7 @@ def build_design_matrices(
if isinstance(NA_action, str):
NA_action = NAAction(NA_action)
if return_type == "dataframe" and not have_pandas:
- raise PatsyError(
- "pandas.DataFrame was requested, but pandas " "is not installed"
- )
+ raise PatsyError("pandas.DataFrame was requested, but pandas is not installed")
if return_type not in ("matrix", "dataframe"):
raise PatsyError(
"unrecognized output type %r, should be "
=====================================
patsy/categorical.py
=====================================
@@ -354,7 +354,7 @@ def categorical_to_int(data, levels, NA_action, origin=None):
level_to_int = dict(zip(levels, range(len(levels))))
except TypeError:
raise PatsyError(
- "Error interpreting categorical data: " "all items must be hashable", origin
+ "Error interpreting categorical data: all items must be hashable", origin
)
# fastpath to avoid doing an item-by-item iteration over boolean arrays,
=====================================
patsy/constraint.py
=====================================
@@ -314,7 +314,7 @@ class _EvalConstraint(object):
right = self.eval(tree.args[1])
if not self.is_constant(right):
raise PatsyError(
- "Can't divide by a variable in a linear " "constraint", tree.args[1]
+ "Can't divide by a variable in a linear constraint", tree.args[1]
)
return left / right[-1]
@@ -327,7 +327,7 @@ class _EvalConstraint(object):
return left * right[-1]
else:
raise PatsyError(
- "Can't multiply one variable by another " "in a linear constraint", tree
+ "Can't multiply one variable by another in a linear constraint", tree
)
def _eval_binary_eq(self, tree):
=====================================
patsy/desc.py
=====================================
@@ -298,7 +298,7 @@ def _eval_binary_minus(evaluator, tree):
def _check_interactable(expr):
if expr.intercept:
raise PatsyError(
- "intercept term cannot interact with " "anything else",
+ "intercept term cannot interact with anything else",
expr.intercept_origin,
)
@@ -392,7 +392,7 @@ def _eval_one(evaluator, tree):
def _eval_number(evaluator, tree):
- raise PatsyError("numbers besides '0' and '1' are " "only allowed with **", tree)
+ raise PatsyError("numbers besides '0' and '1' are only allowed with **", tree)
def _eval_python_expr(evaluator, tree):
@@ -437,14 +437,14 @@ class Evaluator(object):
key = (tree.type, len(tree.args))
if key not in self._evaluators:
raise PatsyError(
- "I don't know how to evaluate this " "'%s' operator" % (tree.type,),
+ "I don't know how to evaluate this '%s' operator" % (tree.type,),
tree.token,
)
result = self._evaluators[key](self, tree)
if require_evalexpr and not isinstance(result, IntermediateExpr):
if isinstance(result, ModelDesc):
raise PatsyError(
- "~ can only be used once, and " "only at the top level", tree
+ "~ can only be used once, and only at the top level", tree
)
else:
raise PatsyError(
=====================================
patsy/design_info.py
=====================================
@@ -88,14 +88,14 @@ class FactorInfo:
if self.type == "numerical":
if not isinstance(num_columns, int):
raise ValueError(
- "For numerical factors, num_columns " "must be an integer"
+ "For numerical factors, num_columns must be an integer"
)
if categories is not None:
- raise ValueError("For numerical factors, categories " "must be None")
+ raise ValueError("For numerical factors, categories must be None")
else:
assert self.type == "categorical"
if num_columns is not None:
- raise ValueError("For categorical factors, num_columns " "must be None")
+ raise ValueError("For categorical factors, num_columns must be None")
categories = tuple(categories)
self.num_columns = num_columns
self.categories = categories
@@ -280,8 +280,7 @@ class DesignInfo(object):
if (factor_infos is None) != (term_codings is None):
raise ValueError(
- "Must specify either both or neither of "
- "factor_infos= and term_codings="
+ "Must specify either both or neither of factor_infos= and term_codings="
)
self.factor_infos = factor_infos
@@ -304,7 +303,7 @@ class DesignInfo(object):
term_factors = set(term.factors)
for subterm in subterms:
if not isinstance(subterm, SubtermInfo):
- raise ValueError("expected SubtermInfo, " "not %r" % (subterm,))
+ raise ValueError("expected SubtermInfo, not %r" % (subterm,))
if not term_factors.issuperset(subterm.factors):
raise ValueError("unexpected factors in subterm")
@@ -312,9 +311,7 @@ class DesignInfo(object):
for term in self.term_codings:
all_factors.update(term.factors)
if all_factors != set(self.factor_infos):
- raise ValueError(
- "Provided Term objects and factor_infos " "do not match"
- )
+ raise ValueError("Provided Term objects and factor_infos do not match")
for factor, factor_info in self.factor_infos.items():
if not isinstance(factor_info, FactorInfo):
raise ValueError(
@@ -343,8 +340,7 @@ class DesignInfo(object):
exp_cols *= cm.shape[1]
if cat_factors != set(subterm.contrast_matrices):
raise ValueError(
- "Mismatch between contrast_matrices "
- "and categorical factors"
+ "Mismatch between contrast_matrices and categorical factors"
)
if exp_cols != subterm.num_columns:
raise ValueError("Unexpected num_columns")
@@ -368,7 +364,7 @@ class DesignInfo(object):
idx += term_columns
if idx != len(self.column_names):
raise ValueError(
- "mismatch between column_names and columns " "coded by given terms"
+ "mismatch between column_names and columns coded by given terms"
)
self.term_name_slices = OrderedDict(
[(term.name(), slice_) for (term, slice_) in self.term_slices.items()]
=====================================
patsy/eval.py
=====================================
@@ -526,7 +526,7 @@ class EvalFactor(object):
# original code
if has_bare_variable_reference(state["transforms"], self.code):
raise PatsyError(
- "names of this form are reserved for " "internal use (%s)" % (token,),
+ "names of this form are reserved for internal use (%s)" % (token,),
token.origin,
)
# Pull out all the '_patsy_stobj0__center__.transform(x)' pieces
=====================================
patsy/highlevel.py
=====================================
@@ -107,7 +107,7 @@ def incr_dbuilder(formula_like, data_iter_maker, eval_env=0, NA_action="drop"):
raise PatsyError("bad formula-like object")
if len(design_infos[0].column_names) > 0:
raise PatsyError(
- "encountered outcome variables for a model " "that does not expect them"
+ "encountered outcome variables for a model that does not expect them"
)
return design_infos[1]
@@ -149,9 +149,7 @@ def incr_dbuilders(formula_like, data_iter_maker, eval_env=0, NA_action="drop"):
# any object with a special method __patsy_get_model_desc__
def _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type):
if return_type == "dataframe" and not have_pandas:
- raise PatsyError(
- "pandas.DataFrame was requested, but pandas " "is not installed"
- )
+ raise PatsyError("pandas.DataFrame was requested, but pandas is not installed")
if return_type not in ("matrix", "dataframe"):
raise PatsyError(
"unrecognized output type %r, should be "
@@ -219,7 +217,7 @@ def _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type):
if rhs_orig_index is not None and lhs_orig_index is not None:
if not rhs_orig_index.equals(lhs_orig_index):
raise PatsyError(
- "index mismatch: outcome and " "predictor have incompatible indexes"
+ "index mismatch: outcome and predictor have incompatible indexes"
)
if return_type == "dataframe":
if rhs_orig_index is not None and lhs_orig_index is None:
@@ -298,7 +296,7 @@ def dmatrix(formula_like, data={}, eval_env=0, NA_action="drop", return_type="ma
)
if lhs.shape[1] != 0:
raise PatsyError(
- "encountered outcome variables for a model " "that does not expect them"
+ "encountered outcome variables for a model that does not expect them"
)
return rhs
=====================================
patsy/mgcv_cubic_splines.py
=====================================
@@ -161,7 +161,7 @@ def _row_tensor_product(dms):
for dm in dms:
if dm.shape[0] != tp_nrows:
raise ValueError(
- "Tensor product arguments should have " "same number of rows."
+ "Tensor product arguments should have same number of rows."
)
tp_ncols *= dm.shape[1]
tp = np.zeros((tp_nrows, tp_ncols))
@@ -624,7 +624,7 @@ class CubicRegressionSpline(object):
x = x[:, 0]
if x.ndim > 1:
raise ValueError(
- "Input to %r must be 1-d, " "or a 2-d column vector." % (self._name,)
+ "Input to %r must be 1-d, or a 2-d column vector." % (self._name,)
)
self._tmp.setdefault("xs", []).append(x)
@@ -649,7 +649,7 @@ class CubicRegressionSpline(object):
else:
constraints = np.atleast_2d(constraints)
if constraints.ndim != 2:
- raise ValueError("Constraints must be 2-d array or " "1-d vector.")
+ raise ValueError("Constraints must be 2-d array or 1-d vector.")
n_constraints = constraints.shape[0]
n_inner_knots = None
@@ -704,7 +704,7 @@ class CubicRegressionSpline(object):
x = x[:, 0]
if x.ndim > 1:
raise ValueError(
- "Input to %r must be 1-d, " "or a 2-d column vector." % (self._name,)
+ "Input to %r must be 1-d, or a 2-d column vector." % (self._name,)
)
dm = _get_crs_dmatrix(
x, self._all_knots, self._constraints, cyclic=self._cyclic
@@ -982,7 +982,7 @@ class TE(object):
else:
constraints = np.atleast_2d(constraints)
if constraints.ndim != 2:
- raise ValueError("Constraints must be 2-d array or " "1-d vector.")
+ raise ValueError("Constraints must be 2-d array or 1-d vector.")
self._constraints = constraints
@@ -992,7 +992,7 @@ class TE(object):
arg = atleast_2d_column_default(arg)
if arg.ndim != 2:
raise ValueError(
- "Each tensor product argument must be " "a 2-d array or 1-d vector."
+ "Each tensor product argument must be a 2-d array or 1-d vector."
)
args_2d.append(arg)
@@ -1190,7 +1190,7 @@ def test_te_2smooths():
assert np.allclose(dmatrix_nocons, dmatrix_R_nocons, rtol=1e-12, atol=0.0)
builder = incr_dbuilder(
- "te(cr(x1, df=5), cc(x2, df=6), " "constraints='center') - 1",
+ "te(cr(x1, df=5), cc(x2, df=6), constraints='center') - 1",
lambda: iter(data_chunked),
)
dmatrix_cons = build_design_matrices([builder], new_data)[0]
=====================================
patsy/missing.py
=====================================
@@ -183,7 +183,7 @@ class NAAction(object):
total_mask |= is_NA
good_mask = ~total_mask
# "..." to handle 1- versus 2-dim indexing
- return [v[good_mask, ...] for v in values]
+ return [v[good_mask] if v.ndim == 1 else v[good_mask, ...] for v in values]
__getstate__ = no_pickling
=====================================
patsy/parse_formula.py
=====================================
@@ -69,7 +69,7 @@ def _read_python_expr(it, end_tokens):
return Token(token_type, Origin.combine(origins), extra=expr_text)
else:
raise PatsyError(
- "unclosed bracket in embedded Python " "expression", Origin.combine(origins)
+ "unclosed bracket in embedded Python expression", Origin.combine(origins)
)
=====================================
patsy/splines.py
=====================================
@@ -171,7 +171,7 @@ class BS(object):
if x.ndim == 2 and x.shape[1] == 1:
x = x[:, 0]
if x.ndim > 1:
- raise ValueError("input to 'bs' must be 1-d, " "or a 2-d column vector")
+ raise ValueError("input to 'bs' must be 1-d, or a 2-d column vector")
# There's no better way to compute exact quantiles than memorizing
# all data.
self._tmp.setdefault("xs", []).append(x)
=====================================
patsy/test_highlevel.py
=====================================
@@ -979,3 +979,21 @@ def test_C_and_pandas_categorical():
assert np.allclose(
dmatrix("C(obj, levels=['a', 'b'])", d), [[1, 0], [1, 1], [1, 0]]
)
+
+
+def test_NAActioon_pandas_string_index():
+ if not have_pandas:
+ return
+ from patsy.missing import NAAction
+
+ formula = "1 + x + z"
+ action = NAAction("drop")
+ data = pandas.DataFrame(
+ {"z": [1.0, np.nan, 2.0], "x": [1, 2, 3]}, index=["a", "b", "c"]
+ )
+ dm = dmatrix(formula, data, 0, NA_action=action, return_type="dataframe")
+ di = dm.design_info
+ data2 = pandas.DataFrame({"z": [4.0, 5.0], "x": [6, 7]})
+ dm2 = dmatrix(di, data2, 0, return_type="dataframe")
+ assert np.allclose(dm2, [[1.0, 6.0, 4.0], [1.0, 7.0, 5.0]])
+ assert list(dm2.columns) == ["Intercept", "x", "z"]
=====================================
patsy/tokens.py
=====================================
@@ -38,7 +38,7 @@ def python_tokenize(code):
origin = Origin(code, start, end)
if pytype == tokenize.ERRORTOKEN:
raise PatsyError(
- "error tokenizing input " "(maybe an unclosed string?)", origin
+ "error tokenizing input (maybe an unclosed string?)", origin
)
if pytype == tokenize.COMMENT:
raise PatsyError("comments are not allowed", origin)
=====================================
patsy/util.py
=====================================
@@ -40,14 +40,19 @@ from .compat import optional_dep_ok
try:
import pandas
except ImportError:
- have_pandas = False
+ PANDAS3 = have_pandas = False
else:
have_pandas = True
+ import packaging.version
+
+ pandas_version = packaging.version.parse(pandas.__version__)
+ PANDAS3 = pandas_version >= packaging.version.parse("3.0.0.dev0")
# Pandas versions < 0.9.0 don't have Categorical
# Can drop this guard whenever we drop support for such older versions of
# pandas.
have_pandas_categorical = have_pandas and hasattr(pandas, "Categorical")
+have_pandas_string_dtype = have_pandas and hasattr(pandas, "StringDtype")
if not have_pandas:
_pandas_is_categorical_dtype = None
else:
@@ -65,6 +70,11 @@ else:
)
have_pandas_categorical_dtype = _pandas_is_categorical_dtype is not None
+
+def safe_is_pandas_string_dtype(x):
+ return have_pandas_string_dtype and isinstance(x, pandas.StringDtype)
+
+
# The handling of the `copy` keyword has been changed since numpy>=2.
# https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword
# If numpy<2 support is dropped, this try-clause can be removed.
@@ -118,7 +128,9 @@ def test_asarray_or_pandas():
assert s_view1.name == "A"
assert np.array_equal(s_view1.index, [10, 20, 30])
s_view1[10] = 101
- assert s[10] == 101
+ # pandas 3 uses copy-on-write, so no longer valid
+ if not PANDAS3:
+ assert s[10] == 101
s_copy = asarray_or_pandas(s, copy=True)
assert s_copy.name == "A"
assert np.array_equal(s_copy.index, [10, 20, 30])
@@ -130,14 +142,18 @@ def test_asarray_or_pandas():
assert s_view2.name == "A"
assert np.array_equal(s_view2.index, [10, 20, 30])
s_view2[10] = 99
- assert s[10] == 99
+ # pandas 3 uses copy-on-write, so no longer valid
+ if not PANDAS3:
+ assert s[10] == 99
df = pandas.DataFrame([[1, 2, 3]], columns=["A", "B", "C"], index=[10])
df_view1 = asarray_or_pandas(df)
df_view1.loc[10, "A"] = 101
assert np.array_equal(df_view1.columns, ["A", "B", "C"])
assert np.array_equal(df_view1.index, [10])
- assert df.loc[10, "A"] == 101
+ # pandas 3 uses copy-on-write, so no longer valid
+ if not PANDAS3:
+ assert df.loc[10, "A"] == 101
df_copy = asarray_or_pandas(df, copy=True)
assert np.array_equal(df_copy, df)
assert np.array_equal(df_copy.columns, ["A", "B", "C"])
@@ -799,7 +815,8 @@ def test_safe_is_pandas_categorical():
# https://github.com/pydata/pandas/issues/9581
# https://github.com/pydata/pandas/issues/9581#issuecomment-77099564
def safe_issubdtype(dt1, dt2):
- if safe_is_pandas_categorical_dtype(dt1):
+ # The second condition is needed to support pandas >= 3 (!)
+ if safe_is_pandas_categorical_dtype(dt1) or safe_is_pandas_string_dtype(dt1):
return False
return np.issubdtype(dt1, dt2)
=====================================
patsy/version.py
=====================================
@@ -6,15 +6,15 @@
# places -- it is imported by patsy/__init__.py, execfile'd by setup.py, etc.
# We use a simple scheme:
-# 1.0.1 -> 1.0.1+dev -> 1.1.0 -> 1.1.0+dev
+# 1.0.2 -> 1.0.2+dev -> 1.1.0 -> 1.1.0+dev
# where the +dev versions are never released into the wild, they're just what
# we stick into the VCS in between releases.
#
# This is compatible with PEP 440:
# http://legacy.python.org/dev/peps/pep-0440/
# via the use of the "local suffix" "+dev", which is disallowed on index
-# servers and causes 1.0.1+dev to sort after plain 1.0.1, which is what we
-# want. (Contrast with the special suffix 1.0.1.dev, which sorts *before*
-# 1.0.1.)
+# servers and causes 1.0.2+dev to sort after plain 1.0.2, which is what we
+# want. (Contrast with the special suffix 1.0.2.dev, which sorts *before*
+# 1.0.2.)
-__version__ = "1.0.1"
+__version__ = "1.0.2"
=====================================
tox.ini
=====================================
@@ -1,5 +1,5 @@
[tox]
-envlist = {py36,py37,py38,py39,py310,py311,py312,py313}-{with_pandas,without_pandas}
+envlist = {py36,py37,py38,py39,py310,py311,py312,py313,py314}-{with_pandas,without_pandas}
[gh-actions]
python =
@@ -11,6 +11,7 @@ python =
3.11: py311
3.12: py312
3.13: py313
+ 3.14: py314
[testenv]
deps=
View it on GitLab: https://salsa.debian.org/med-team/patsy/-/compare/4fdcab7e86d5cfd63fb962b6c2526fa486706760...381ad3afc10fa65acf2665af66e6480556b4ee17
--
View it on GitLab: https://salsa.debian.org/med-team/patsy/-/compare/4fdcab7e86d5cfd63fb962b6c2526fa486706760...381ad3afc10fa65acf2665af66e6480556b4ee17
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20251025/5a837d51/attachment-0001.htm>
More information about the debian-med-commit
mailing list