Summary
Four small, independent defects found while auditing the package. None is urgent; grouped
here to avoid four near-empty issues. Happy to split them if the maintainers prefer one
issue per item.
1. resolve_locations misaligns importance with the sorted locations
pretab/core/locations.py:83-87 sorts and dedupes locs and then passes the caller's
original-order importance array to trim_to_count, so index i of importance no longer
refers to locs[i]. The wrong locations are kept.
import numpy as np
from pretab.core.locations import resolve_locations
locs = np.array([5.0, 1.0, 3.0])
imp = np.array([0.1, 9.9, 0.2]) # location 1.0 is by far the most important
print(resolve_locations(locs, min_count=1, max_count=1, importance=imp))
Expected [1.]. Currently unreachable — nothing in the package calls
resolve_locations; it is only re-exported by pretab/core/__init__.py:34. So this is a
latent trap for whoever wires it up rather than a live bug, but it is exported API.
Fix: reorder importance alongside locs, e.g. sort with np.argsort and index
importance by the same permutation before the dedupe, or drop the importance parameter
until there is a caller.
2. get_feature_names_out silently truncates a wrong-length input_features
pretab/core/base.py:55 uses zip(input_features, self._output_sizes(), strict=False), so
passing too few names quietly returns a short array instead of raising. scikit-learn's
convention is to validate with _check_feature_names_in and raise on a length mismatch.
Fix: validate len(input_features) == self.n_features_in_ and raise InvalidParamError, or
use strict=True.
3. NumPy input produces doubled name prefixes
import numpy as np
from pretab import Preprocessor
pre = Preprocessor(numerical_method="minmax").fit(np.random.default_rng(0).normal(size=(50, 2)), None)
print(list(pre.get_feature_names_out()))
['num_feature_0__feature_0', 'num_feature_1__feature_1']
Preprocessor.fit synthesises column names as feature_{i} (pretab/preprocessor.py:345)
and then names each ColumnTransformer entry num_{feature} (preprocessor.py:394), so the
ColumnTransformer's {name}__{column} joining repeats the stem. Cosmetic, but it is what
users see in the array's column labels.
Fix: nothing structural — either accept it, or synthesise plainer stems (x{i}) for ndarray
input so the result reads num_x0__x0.
4. LanguageEmbeddingTransformer docstring example cannot run
pretab/transformers/embeddings/language_transformer.py:76 does X.shape[1], but the
docstring example at :39 passes a plain list:
>>> embeddings = transformer.fit_transform([["red"], ["blue"], ["green"]]) # doctest: +SKIP
A list has no .shape, so this raises AttributeError. It is masked by # doctest: +SKIP,
so CI does not catch it. transform already normalises with np.asarray
(language_transformer.py:105-107); fit does not.
Fix: apply the same np.asarray normalisation in fit — which also makes the documented
example work and lets the +SKIP be narrowed to just the model-loading lines.
Environment
- pretab 0.1.0 (
main @ 51c3043)
- Python 3.11.15, numpy 2.4.6, pandas 2.3.3, scikit-learn 1.9.0, scipy 1.17.1
- macOS (darwin 25.5.0)
Summary
Four small, independent defects found while auditing the package. None is urgent; grouped
here to avoid four near-empty issues. Happy to split them if the maintainers prefer one
issue per item.
1.
resolve_locationsmisalignsimportancewith the sorted locationspretab/core/locations.py:83-87sorts and dedupeslocsand then passes the caller'soriginal-order
importancearray totrim_to_count, so indexiofimportanceno longerrefers to
locs[i]. The wrong locations are kept.Expected
[1.]. Currently unreachable — nothing in the package callsresolve_locations; it is only re-exported bypretab/core/__init__.py:34. So this is alatent trap for whoever wires it up rather than a live bug, but it is exported API.
Fix: reorder
importancealongsidelocs, e.g. sort withnp.argsortand indeximportanceby the same permutation before the dedupe, or drop theimportanceparameteruntil there is a caller.
2.
get_feature_names_outsilently truncates a wrong-lengthinput_featurespretab/core/base.py:55useszip(input_features, self._output_sizes(), strict=False), sopassing too few names quietly returns a short array instead of raising. scikit-learn's
convention is to validate with
_check_feature_names_inand raise on a length mismatch.Fix: validate
len(input_features) == self.n_features_in_and raiseInvalidParamError, oruse
strict=True.3. NumPy input produces doubled name prefixes
Preprocessor.fitsynthesises column names asfeature_{i}(pretab/preprocessor.py:345)and then names each
ColumnTransformerentrynum_{feature}(preprocessor.py:394), so theColumnTransformer's{name}__{column}joining repeats the stem. Cosmetic, but it is whatusers see in the array's column labels.
Fix: nothing structural — either accept it, or synthesise plainer stems (
x{i}) for ndarrayinput so the result reads
num_x0__x0.4.
LanguageEmbeddingTransformerdocstring example cannot runpretab/transformers/embeddings/language_transformer.py:76doesX.shape[1], but thedocstring example at
:39passes a plain list:A list has no
.shape, so this raisesAttributeError. It is masked by# doctest: +SKIP,so CI does not catch it.
transformalready normalises withnp.asarray(
language_transformer.py:105-107);fitdoes not.Fix: apply the same
np.asarraynormalisation infit— which also makes the documentedexample work and lets the
+SKIPbe narrowed to just the model-loading lines.Environment
main@ 51c3043)