Compare commits

..
Author SHA1 Message Date
atarashansky 88c9c09ec6 chore: upgrade dependencies 2023-11-29 11:56:03 -08:00
20 changed files with 2413 additions and 19323 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 1.2.0 current_version = 1.1.2
commit = True commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<prerel>rc)\.(?P<prerelversion>\d+))? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<prerel>rc)\.(?P<prerelversion>\d+))?
serialize = serialize =
+22 -16
View File
@@ -7,10 +7,6 @@ on:
branches: branches:
- main - main
### For debugging purposes - uncomment below to run on all PRs
pull_request:
branches: "*"
env: env:
JEST_ENV: prod JEST_ENV: prod
@@ -18,9 +14,9 @@ jobs:
docker-build: docker-build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Build docker image - name: Build docker image
@@ -33,23 +29,34 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
# note: The `macos-latest` is latest Catalina version, and not Big Sur. So we explicitly ask for Big Sur (`macos-11`) # note: The `macos-latest` is latest Catalina version, and not Big Sur. So we explicitly ask for Big Sur (`macos-11`)
os: [ubuntu-latest, macos-latest, macos-13] os: [ubuntu-latest, macos-latest, macos-11]
python-version: ["3.10", "3.11", "3.12"] python-version: [3.6, 3.7, 3.8, 3.9]
cellxgene_build: [main, latest] cellxgene_build: [main, latest]
exclude:
# 3.6 no longer avail on Big Sur (`macos-11`)
- os: macos-11
python-version: 3.6
# no pypi build exists for macos+py3.9 and source install fails to
# install `tables` py pkg (a `scanpy` dependency), so we test py3.9
# only on ubuntu
- os: macos-11
python-version: 3.9
- os: macos-latest
python-version: 3.9
# add anndata pinned version test for subset of matrix configurations, # add anndata pinned version test for subset of matrix configurations,
# in order to reduce matrix cross-product explosion # in order to reduce matrix cross-product explosion
include: include:
- python-version: 3.12 - python-version: 3.9
cellxgene_build: latest cellxgene_build: latest
# TODO: dynamically use the literal version in requirements.txt, # TODO: dynamically use the literal version in requirements.txt,
# to avoid having to update this in manually in the future # to avoid having to update this in manually in the future
# TODO: Do not bother running this if anndata latest version # TODO: Do not bother running this if anndata latest version
# matches this pinned version, to avoid a redundant test # matches this pinned version, to avoid a redundant test
anndata_version: "==0.10.9" anndata_version: "==0.10.3"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Cache env vars - name: Cache env vars
@@ -59,14 +66,14 @@ jobs:
run: echo "BREW_CACHE=`brew --cache`" >> $GITHUB_ENV run: echo "BREW_CACHE=`brew --cache`" >> $GITHUB_ENV
# FIXME: Only working for Linux # FIXME: Only working for Linux
- name: Python cache - name: Python cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ${{ env.PIP_CACHE }} path: ${{ env.PIP_CACHE }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Node cache - name: Node cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -74,7 +81,7 @@ jobs:
${{ runner.os }}-node- ${{ runner.os }}-node-
- name: Brew cache (MacOS) - name: Brew cache (MacOS)
if: startsWith(matrix.os, 'macos') if: startsWith(matrix.os, 'macos')
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ${{ env.BREW_CACHE }} path: ${{ env.BREW_CACHE }}
key: ${{ runner.os }}-brew- key: ${{ runner.os }}-brew-
@@ -100,7 +107,6 @@ jobs:
# keep same pip pkg versions as in the cxg release # keep same pip pkg versions as in the cxg release
sed -i'' -e 's/-r requirements.txt//' server/requirements-dev.txt sed -i'' -e 's/-r requirements.txt//' server/requirements-dev.txt
pip install -r server/requirements-dev.txt pip install -r server/requirements-dev.txt
pip install --force-reinstall numpy==2.0.1 numba>=0.60.0 pandas
- name: Install anndata version per matrix variable - name: Install anndata version per matrix variable
run: pip install anndata${{ matrix.anndata_version }} run: pip install anndata${{ matrix.anndata_version }}
- name: Install node - name: Install node
+18 -21
View File
@@ -14,28 +14,25 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- run: | - run: |
git fetch --depth=1 origin +${{github.base_ref}} git fetch --depth=1 origin +${{github.base_ref}}
- name: Set up Python 3.12 - name: Set up Python 3.9
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: 3.12 python-version: 3.9
- name: Node cache - name: Node cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: | restore-keys: |
${{ runner.os }}-node- ${{ runner.os }}-node-
- name: Install dependencies now - name: Install dependencies
run: | run: |
pip install flake8 pip install flake8
pip install black pip install black
pip install setuptools cd client
- name: Install client dependencies
run: |
cd client
npm install npm install
- name: Format with black and lint with flake8 - name: Format with black and lint with flake8
run: | run: |
@@ -48,22 +45,22 @@ jobs:
unit-test: unit-test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Set up Python 3.12 (pyenv) # pyenv needed for mlflow in cli annotate tests - name: Set up Python 3.9 (pyenv) # pyenv needed for mlflow in cli annotate tests
uses: gabrielfalcao/pyenv-action@v9 uses: gabrielfalcao/pyenv-action@v9
with: with:
default: 3.12 default: 3.9
command: pip install -U pip # upgrade pip after installing python command: pip install -U pip # upgrade pip after installing python
- run: pip install virtualenv # virtualenv needed for mlflow in cli annotate tests - run: pip install virtualenv # virtualenv needed for mlflow in cli annotate tests
- name: Python cache - name: Python cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.cache/pip path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Node cache - name: Node cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -81,20 +78,20 @@ jobs:
runs-on: macos-latest runs-on: macos-latest
timeout-minutes: 20 timeout-minutes: 20
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Set up Python 3.12 - name: Set up Python 3.9
uses: actions/setup-python@v5 uses: actions/setup-python@v4
with: with:
python-version: 3.12 python-version: 3.9
- name: Python cache - name: Python cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.cache/pip path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Node cache - name: Node cache
uses: actions/cache@v4 uses: actions/cache@v1
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
+1 -1
View File
@@ -58,7 +58,7 @@ Please [file an issue](https://github.com/chanzuckerberg/cellxgene/issues/new/ch
### Finding help ### Finding help
We'd love to hear from you! We'd love to hear from you!
For questions, suggestions, or accolades, join the `#cellxgene-users` channel on the [CZI Science Community Slack](https://czi.co/science-slack) and say "hi!". For questions, suggestions, or accolades, [join the `#cellxgene-users` channel on the CZI Science Slack](https://join-cellxgene-users.herokuapp.com/) and say "hi!".
For any errors, [report bugs on Github](https://github.com/chanzuckerberg/cellxgene/issues). For any errors, [report bugs on Github](https://github.com/chanzuckerberg/cellxgene/issues).
-1
View File
@@ -1 +0,0 @@
16.20.0
+1 -1
View File
@@ -13,7 +13,7 @@ import * as ENV_DEFAULT from "../../../environment.default.json";
// a test can take more time to finish, so we don't want // a test can take more time to finish, so we don't want
// jest to shut off the test too soon // jest to shut off the test too soon
jest.setTimeout(2 * 60 * 1000); jest.setTimeout(2 * 60 * 1000);
setDefaultOptions({ timeout: 60 * 1000 }); setDefaultOptions({ timeout: 20 * 1000 });
jest.retryTimes(ENV_DEFAULT.RETRY_ATTEMPTS); jest.retryTimes(ENV_DEFAULT.RETRY_ATTEMPTS);
+2308 -19223
View File
File diff suppressed because it is too large Load Diff
+6 -7
View File
@@ -1,6 +1,6 @@
{ {
"name": "cellxgene", "name": "cellxgene",
"version": "1.2.0", "version": "1.1.2",
"license": "MIT", "license": "MIT",
"description": "cellxgene is a web application for the interactive exploration of single cell sequence data.", "description": "cellxgene is a web application for the interactive exploration of single cell sequence data.",
"repository": "https://github.com/chanzuckerberg/cellxgene", "repository": "https://github.com/chanzuckerberg/cellxgene",
@@ -18,8 +18,7 @@
}, },
"engineStrict": true, "engineStrict": true,
"engines": { "engines": {
"npm": ">=3.0.0", "npm": ">=3.0.0"
"node": "^16.0.0"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "./configuration/eslint/eslint.js" "extends": "./configuration/eslint/eslint.js"
@@ -78,7 +77,7 @@
"whatwg-fetch": "^3.2.0" "whatwg-fetch": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.13.16",
"@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-decorators": "^7.13.15", "@babel/plugin-proposal-decorators": "^7.13.15",
"@babel/plugin-proposal-export-namespace-from": "^7.10.4", "@babel/plugin-proposal-export-namespace-from": "^7.10.4",
@@ -124,7 +123,7 @@
"jest-circus": "^27.0.6", "jest-circus": "^27.0.6",
"jest-environment-puppeteer": "^5.0.1", "jest-environment-puppeteer": "^5.0.1",
"jest-fetch-mock": "^3.0.3", "jest-fetch-mock": "^3.0.3",
"jest-puppeteer": "^6.2.0", "jest-puppeteer": "^5.0.1",
"json-loader": "^0.5.7", "json-loader": "^0.5.7",
"lint-staged": "^10.2.11", "lint-staged": "^10.2.11",
"lodash": "^4.17.21", "lodash": "^4.17.21",
@@ -135,11 +134,11 @@
"lodash.zip": "^4.2.0", "lodash.zip": "^4.2.0",
"mini-css-extract-plugin": "^1.5.0", "mini-css-extract-plugin": "^1.5.0",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"puppeteer": "^10.4.0", "puppeteer": "^8.0.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"serve-favicon": "^2.5.0", "serve-favicon": "^2.5.0",
"terser-webpack-plugin": "^5.1.1", "terser-webpack-plugin": "^5.1.1",
"webpack": "^5.94.0", "webpack": "^5.88.2",
"webpack-cli": "^4.6.0", "webpack-cli": "^4.6.0",
"webpack-dev-middleware": "^4.1.0", "webpack-dev-middleware": "^4.1.0",
"webpack-merge": "^5.0.9", "webpack-merge": "^5.0.9",
@@ -16,7 +16,7 @@ const InformationMenu = React.memo((props) => {
rel="noopener" rel="noopener"
/> />
<MenuItem <MenuItem
href="https://czi.co/science-slack" href="https://join-cellxgene-users.herokuapp.com/"
target="_blank" target="_blank"
icon="chat" icon="chat"
text="Chat" text="Chat"
+1 -1
View File
@@ -2,7 +2,7 @@ import logging
import sys import sys
from server.common.utils.utils import import_plugins from server.common.utils.utils import import_plugins
__version__ = "1.2.0" __version__ = "1.1.2"
display_version = "cellxgene v" + __version__ display_version = "cellxgene v" + __version__
try: try:
+1 -1
View File
@@ -176,7 +176,7 @@ class DatasetConfig(BaseConfig):
self.validate_correct_type_of_configuration_attribute("diffexp__top_n", int) self.validate_correct_type_of_configuration_attribute("diffexp__top_n", int)
data_adaptor = self.get_data_adaptor() data_adaptor = self.get_data_adaptor()
if self.diffexp__enable and data_adaptor.parameters.get("diffexp-may-be-slow", False): if self.diffexp__enable and data_adaptor.parameters.get("diffexp_may_be_slow", False):
context["messagefn"]( context["messagefn"](
"CAUTION: due to the size of your dataset, " "running differential expression may take longer or fail." "CAUTION: due to the size of your dataset, " "running differential expression may take longer or fail."
) )
+2 -1
View File
@@ -116,7 +116,7 @@ def _get_type_info(array: Union[np.ndarray, pd.Series, pd.Index]) -> Tuple[np.dt
raise TypeError("Unsupported data type.") raise TypeError("Unsupported data type.")
dtype = array.dtype dtype = array.dtype
res = _get_type_info_from_dtype(dtype) res = _get_type_info_from_dtype(dtype)
if res is not None: if res is not None:
return res return res
@@ -140,6 +140,7 @@ def _get_type_info(array: Union[np.ndarray, pd.Series, pd.Index]) -> Tuple[np.dt
if dtype.kind in ["i", "u"] and _can_cast_array_values_to_int32(array): if dtype.kind in ["i", "u"] and _can_cast_array_values_to_int32(array):
return (np.int32, {"type": "int32"}) return (np.int32, {"type": "int32"})
if dtype.kind == "f": if dtype.kind == "f":
_float64_warning(array.dtype) _float64_warning(array.dtype)
return (np.float32, {"type": "float32"}) return (np.float32, {"type": "float32"})
+1 -1
View File
@@ -211,7 +211,7 @@ class AnndataAdaptor(DataAdaptor):
# heuristic # heuristic
n_values = self.data.shape[0] * self.data.shape[1] n_values = self.data.shape[0] * self.data.shape[1]
if (n_values > 1e8 and self.server_config.adaptor__anndata_adaptor__backed is True) or (n_values > 5e8): if (n_values > 1e8 and self.server_config.adaptor__anndata_adaptor__backed is True) or (n_values > 5e8):
self.parameters.update({"diffexp-may-be-slow": True}) self.parameters.update({"diffexp_may_be_slow": True})
def _is_valid_layout(self, arr): def _is_valid_layout(self, arr):
"""return True if this layout data is a valid array for front-end presentation: """return True if this layout data is a valid array for front-end presentation:
+1 -1
View File
@@ -1,2 +1,2 @@
mlflow==2.16.0 mlflow==1.27.0
scanpy scanpy
+21 -22
View File
@@ -1,23 +1,22 @@
anndata>=0.8.0 anndata==0.10.3
boto3>=1.12.18 boto3==1.29.5
click>=7.1.2 click==8.1.7
Flask>=3.0.0 Flask==3.0.0
Flask-Compress>=1.4.0 Flask-Compress==1.14
Flask-Cors>=3.0.9 Flask-Cors==4.0.0
Flask-RESTful>=0.3.6 Flask-RESTful==0.3.10
flask-server-timing>=0.1.2 flask-server-timing==0.1.2
flask-talisman>=0.7.0 flask-talisman==1.1.0
flatbuffers==2.0.7 flatbuffers==1.12
flatten-dict>=0.2.0 flatten-dict==0.4.2
fsspec>0.8.0 fsspec==2023.10.0
gunicorn>=20.0.4 gunicorn==21.2.0
h5py>=3.0.0 h5py==3.10.0
numba>=0.60.0 numba==0.58.1
numpy==2.0.1 numpy==1.26.2
packaging>=20.0 packaging==23.2
pandas>=2.2.2 pandas<2.0.0
PyYAML>=5.4 # CVE-2020-14343 PyYAML==6.0.1
requests>=2.22.0 requests==2.31.0
s3fs==0.4.2 s3fs==0.4.2
scipy>=1.4 scipy==1.11.4
setuptools
+2 -2
View File
@@ -14,7 +14,7 @@ with open("server/requirements-annotate.txt") as fh:
setup( setup(
name="cellxgene", name="cellxgene",
version="1.2.0", version="1.1.2",
packages=find_packages(), packages=find_packages(),
url="https://github.com/chanzuckerberg/cellxgene", url="https://github.com/chanzuckerberg/cellxgene",
license="MIT", license="MIT",
@@ -24,7 +24,7 @@ setup(
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
install_requires=requirements, install_requires=requirements,
python_requires=">=3.10", python_requires=">=3.6",
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
classifiers=[ classifiers=[
+5
View File
@@ -0,0 +1,5 @@
from .mlflow_model_fixture import FakeModel
def _load_pyfunc(data_path):
return FakeModel()
+10 -10
View File
@@ -65,13 +65,13 @@ class EstDistTest(unittest.TestCase):
# non-finites # non-finites
self.assertEqual(estimate_approximate_distribution(np.array([np.nan])), XApproximateDistribution.NORMAL) self.assertEqual(estimate_approximate_distribution(np.array([np.nan])), XApproximateDistribution.NORMAL)
self.assertEqual(estimate_approximate_distribution(np.array([np.inf])), XApproximateDistribution.NORMAL) self.assertEqual(estimate_approximate_distribution(np.array([np.PINF])), XApproximateDistribution.NORMAL)
self.assertEqual(estimate_approximate_distribution(np.array([np.inf])), XApproximateDistribution.NORMAL) self.assertEqual(estimate_approximate_distribution(np.array([np.NINF])), XApproximateDistribution.NORMAL)
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(np.array([np.inf, np.inf, 0])), XApproximateDistribution.NORMAL estimate_approximate_distribution(np.array([np.PINF, np.NINF, 0])), XApproximateDistribution.NORMAL
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(np.array([np.nan, np.inf, np.inf])), XApproximateDistribution.NORMAL estimate_approximate_distribution(np.array([np.nan, np.PINF, np.NINF])), XApproximateDistribution.NORMAL
) )
raw = np.random.exponential(scale=1000, size=(50, 3)) raw = np.random.exponential(scale=1000, size=(50, 3))
@@ -82,15 +82,15 @@ class EstDistTest(unittest.TestCase):
XApproximateDistribution.COUNT, XApproximateDistribution.COUNT,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(raw, [1], [np.inf])), estimate_approximate_distribution(put(raw, [1], [np.PINF])),
XApproximateDistribution.COUNT, XApproximateDistribution.COUNT,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(raw, [1], [np.inf])), estimate_approximate_distribution(put(raw, [1], [np.NINF])),
XApproximateDistribution.COUNT, XApproximateDistribution.COUNT,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(raw, [1, 3, 88], [np.nan, np.inf, np.inf])), estimate_approximate_distribution(put(raw, [1, 3, 88], [np.nan, np.PINF, np.NINF])),
XApproximateDistribution.COUNT, XApproximateDistribution.COUNT,
) )
self.assertEqual( self.assertEqual(
@@ -103,15 +103,15 @@ class EstDistTest(unittest.TestCase):
XApproximateDistribution.NORMAL, XApproximateDistribution.NORMAL,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(logged, [1], [np.inf])), estimate_approximate_distribution(put(logged, [1], [np.PINF])),
XApproximateDistribution.NORMAL, XApproximateDistribution.NORMAL,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(logged, [1], [np.inf])), estimate_approximate_distribution(put(logged, [1], [np.NINF])),
XApproximateDistribution.NORMAL, XApproximateDistribution.NORMAL,
) )
self.assertEqual( self.assertEqual(
estimate_approximate_distribution(put(logged, [1, 3, 88], [np.nan, np.inf, np.inf])), estimate_approximate_distribution(put(logged, [1, 3, 88], [np.nan, np.PINF, np.NINF])),
XApproximateDistribution.NORMAL, XApproximateDistribution.NORMAL,
) )
self.assertEqual( self.assertEqual(
+2 -2
View File
@@ -16,10 +16,10 @@ class TestJsonifyStrict(unittest.TestCase):
jsonify_strict({"nan": [np.nan]}) jsonify_strict({"nan": [np.nan]})
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
jsonify_strict({"pinf": [np.inf]}) jsonify_strict({"pinf": [np.PINF]})
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
jsonify_strict({"ninf": [np.inf]}) jsonify_strict({"ninf": [np.NINF]})
def test_jsonify_numpy_ndarray(self): def test_jsonify_numpy_ndarray(self):
values = { values = {
+9 -10
View File
@@ -42,7 +42,7 @@ class TestTypeConversionUtils(unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
get_schema_type_hint_from_dtype(np.dtype(dtype)) get_schema_type_hint_from_dtype(np.dtype(dtype))
for dtype in [np.float32, np.float64]: for dtype in [np.float16, np.float32, np.float64]:
self.assertEqual(get_schema_type_hint_from_dtype(np.dtype(dtype)), {"type": "float32"}) self.assertEqual(get_schema_type_hint_from_dtype(np.dtype(dtype)), {"type": "float32"})
for dtype in [np.dtype(object), np.dtype(str)]: for dtype in [np.dtype(object), np.dtype(str)]:
@@ -123,18 +123,17 @@ int_OK_cases = [
float_OK_cases = [ float_OK_cases = [
{ {
"test_case": "float_OK_cases",
"data": data, "data": data,
"expected_encoding_dtype": np.float32, "expected_encoding_dtype": np.float32,
"expected_schema_hint": {"type": "float32"}, "expected_schema_hint": {"type": "float32"},
"logs": None if dtype == np.float32 else {"level": logging.WARNING, "output": "may lose precision"}, "logs": None if data.dtype != np.float64 else {"level": logging.WARNING, "output": "may lose precision"},
} }
for dtype in [np.float32, np.float64] for dtype in [np.float16, np.float32, np.float64]
for data in [ for data in [
np.arange(-128, 1000, dtype=dtype), np.arange(-128, 1000, dtype=dtype),
pd.Series(np.arange(-128, 1000, dtype=dtype)), pd.Series(np.arange(-128, 1000, dtype=dtype)),
pd.Index(np.arange(-129, 1000, dtype=dtype)), pd.Index(np.arange(-129, 1000, dtype=dtype)),
np.array([-np.nan, np.inf, -1, 0.0, 0, 0.0, 1, np.inf, np.nan], dtype=dtype), np.array([-np.nan, np.NINF, -1, np.NZERO, 0, np.PZERO, 1, np.PINF, np.nan], dtype=dtype),
np.array([np.finfo(dtype).min, 0, np.finfo(dtype).max], dtype=dtype), np.array([np.finfo(dtype).min, 0, np.finfo(dtype).max], dtype=dtype),
sparse.csr_matrix((10, 100), dtype=dtype), sparse.csr_matrix((10, 100), dtype=dtype),
] ]
@@ -199,13 +198,12 @@ category_numeric_OK_cases = [
# numeric, no NA/NaN, float # numeric, no NA/NaN, float
*[ *[
{ {
"test_case": "numeric, no NA/NaN, float",
"data": data, "data": data,
"expected_encoding_dtype": np.float32, "expected_encoding_dtype": np.float32,
"expected_schema_hint": {"type": "categorical"}, "expected_schema_hint": {"type": "categorical"},
"logs": None if dtype == np.float32 else {"level": logging.WARNING, "output": "may lose precision"}, "logs": {"level": logging.WARNING, "output": "may lose precision"},
} }
for dtype in [np.float32, np.float64] for dtype in [np.float16, np.float32, np.float64]
for data in [ for data in [
pd.Series(np.array([0, 1, 2], dtype=dtype), dtype="category"), pd.Series(np.array([0, 1, 2], dtype=dtype), dtype="category"),
pd.Series(np.array([0, 1, 2], dtype=dtype), dtype="category").cat.remove_categories([1]), pd.Series(np.array([0, 1, 2], dtype=dtype), dtype="category").cat.remove_categories([1]),
@@ -215,11 +213,10 @@ category_numeric_OK_cases = [
# numeric, has NA-induced cast to float32 # numeric, has NA-induced cast to float32
*[ *[
{ {
"test_case": "numeric, has NA-induced cast to float32",
"data": data, "data": data,
"expected_encoding_dtype": np.float32, "expected_encoding_dtype": np.float32,
"expected_schema_hint": {"type": "categorical"}, "expected_schema_hint": {"type": "categorical"},
"logs": None if dtype == np.float32 else {"level": logging.WARNING, "output": "may lose precision"}, "logs": {"level": logging.WARNING, "output": "may lose precision"},
} }
for dtype in [ for dtype in [
np.int8, np.int8,
@@ -230,6 +227,7 @@ category_numeric_OK_cases = [
np.uint32, np.uint32,
np.int64, np.int64,
np.uint64, np.uint64,
np.float16,
np.float32, np.float32,
np.float64, np.float64,
] ]
@@ -314,6 +312,7 @@ class TestTypeInference(unittest.TestCase, AssertNoLog):
self.assertEqual(encoding_dtype, self.expected_encoding_dtype) self.assertEqual(encoding_dtype, self.expected_encoding_dtype)
self.assertEqual(schema_hint, self.expected_schema_hint) self.assertEqual(schema_hint, self.expected_schema_hint)
self.assertIn(logs["output"], logger.output[0]) self.assertIn(logs["output"], logger.output[0])
else: else:
with self.assertNoLogs(logging.getLogger(), logging.WARNING): with self.assertNoLogs(logging.getLogger(), logging.WARNING):
encoding_dtype, schema_hint = get_dtype_and_schema_of_array(self.data) encoding_dtype, schema_hint = get_dtype_and_schema_of_array(self.data)