maxframe 1.1.0__cp311-cp311-win_amd64.whl → 1.2.0__cp311-cp311-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of maxframe might be problematic. Click here for more details.
- maxframe/__init__.py +1 -1
- maxframe/_utils.cp311-win_amd64.pyd +0 -0
- maxframe/_utils.pxd +1 -1
- maxframe/_utils.pyx +1 -1
- maxframe/codegen.py +14 -7
- maxframe/config/__init__.py +2 -2
- maxframe/config/config.py +33 -1
- maxframe/config/tests/__init__.py +1 -1
- maxframe/config/tests/test_config.py +21 -2
- maxframe/config/tests/test_validators.py +1 -1
- maxframe/config/validators.py +1 -1
- maxframe/conftest.py +9 -3
- maxframe/core/__init__.py +2 -1
- maxframe/core/accessor.py +44 -0
- maxframe/core/base.py +1 -1
- maxframe/core/entity/__init__.py +1 -1
- maxframe/core/entity/core.py +1 -1
- maxframe/core/entity/executable.py +1 -1
- maxframe/core/entity/objects.py +1 -1
- maxframe/core/entity/output_types.py +1 -1
- maxframe/core/entity/tests/__init__.py +1 -1
- maxframe/core/entity/tests/test_objects.py +1 -1
- maxframe/core/entity/tileables.py +1 -1
- maxframe/core/entity/utils.py +1 -1
- maxframe/core/graph/__init__.py +1 -1
- maxframe/core/graph/builder/__init__.py +1 -1
- maxframe/core/graph/builder/base.py +1 -1
- maxframe/core/graph/builder/tileable.py +1 -1
- maxframe/core/graph/builder/utils.py +1 -1
- maxframe/core/graph/core.cp311-win_amd64.pyd +0 -0
- maxframe/core/graph/core.pyx +1 -1
- maxframe/core/graph/entity.py +1 -1
- maxframe/core/graph/tests/__init__.py +1 -1
- maxframe/core/graph/tests/test_graph.py +1 -1
- maxframe/core/mode.py +1 -1
- maxframe/core/operator/__init__.py +1 -1
- maxframe/core/operator/base.py +1 -1
- maxframe/core/operator/core.py +1 -1
- maxframe/core/operator/fetch.py +1 -1
- maxframe/core/operator/objects.py +1 -1
- maxframe/core/operator/shuffle.py +1 -1
- maxframe/core/operator/tests/__init__.py +1 -1
- maxframe/core/operator/tests/test_core.py +1 -1
- maxframe/core/operator/utils.py +1 -1
- maxframe/core/tests/__init__.py +1 -1
- maxframe/core/tests/test_mode.py +1 -1
- maxframe/dataframe/__init__.py +3 -3
- maxframe/dataframe/accessors/__init__.py +15 -0
- maxframe/dataframe/accessors/datetime_/__init__.py +32 -0
- maxframe/dataframe/accessors/datetime_/accessor.py +67 -0
- maxframe/dataframe/{misc/datetimes.py → accessors/datetime_/core.py} +9 -9
- maxframe/dataframe/{plotting → accessors/datetime_}/tests/__init__.py +1 -1
- maxframe/dataframe/accessors/datetime_/tests/test_datetime_accessor.py +41 -0
- maxframe/dataframe/accessors/dict_/__init__.py +43 -0
- maxframe/dataframe/accessors/dict_/accessor.py +38 -0
- maxframe/dataframe/accessors/dict_/contains.py +81 -0
- maxframe/dataframe/accessors/dict_/getitem.py +144 -0
- maxframe/dataframe/accessors/dict_/length.py +72 -0
- maxframe/dataframe/accessors/dict_/remove.py +87 -0
- maxframe/dataframe/accessors/dict_/setitem.py +88 -0
- maxframe/dataframe/accessors/dict_/tests/__init__.py +13 -0
- maxframe/dataframe/accessors/dict_/tests/test_dict_accessor.py +130 -0
- maxframe/dataframe/{plotting → accessors/plotting}/__init__.py +4 -6
- maxframe/dataframe/{plotting → accessors/plotting}/core.py +3 -3
- maxframe/dataframe/accessors/plotting/tests/__init__.py +13 -0
- maxframe/dataframe/{plotting/tests/test_plotting.py → accessors/plotting/tests/test_plotting_accessor.py} +6 -6
- maxframe/dataframe/accessors/string_/__init__.py +32 -0
- maxframe/dataframe/{misc → accessors/string_}/accessor.py +4 -65
- maxframe/dataframe/{misc/string_.py → accessors/string_/core.py} +20 -20
- maxframe/dataframe/accessors/string_/tests/__init__.py +13 -0
- maxframe/dataframe/accessors/string_/tests/test_string_accessor.py +73 -0
- maxframe/dataframe/arithmetic/__init__.py +1 -1
- maxframe/dataframe/arithmetic/abs.py +1 -1
- maxframe/dataframe/arithmetic/add.py +1 -1
- maxframe/dataframe/arithmetic/arccos.py +1 -1
- maxframe/dataframe/arithmetic/arccosh.py +1 -1
- maxframe/dataframe/arithmetic/arcsin.py +1 -1
- maxframe/dataframe/arithmetic/arcsinh.py +1 -1
- maxframe/dataframe/arithmetic/arctan.py +1 -1
- maxframe/dataframe/arithmetic/arctanh.py +1 -1
- maxframe/dataframe/arithmetic/around.py +1 -1
- maxframe/dataframe/arithmetic/bitwise_and.py +1 -1
- maxframe/dataframe/arithmetic/bitwise_or.py +1 -1
- maxframe/dataframe/arithmetic/bitwise_xor.py +1 -1
- maxframe/dataframe/arithmetic/ceil.py +1 -1
- maxframe/dataframe/arithmetic/core.py +1 -1
- maxframe/dataframe/arithmetic/cos.py +1 -1
- maxframe/dataframe/arithmetic/cosh.py +1 -1
- maxframe/dataframe/arithmetic/degrees.py +1 -1
- maxframe/dataframe/arithmetic/docstring.py +1 -1
- maxframe/dataframe/arithmetic/equal.py +1 -1
- maxframe/dataframe/arithmetic/exp.py +1 -1
- maxframe/dataframe/arithmetic/exp2.py +1 -1
- maxframe/dataframe/arithmetic/expm1.py +1 -1
- maxframe/dataframe/arithmetic/floor.py +1 -1
- maxframe/dataframe/arithmetic/floordiv.py +1 -1
- maxframe/dataframe/arithmetic/greater.py +1 -1
- maxframe/dataframe/arithmetic/greater_equal.py +1 -1
- maxframe/dataframe/arithmetic/invert.py +1 -1
- maxframe/dataframe/arithmetic/is_ufuncs.py +1 -1
- maxframe/dataframe/arithmetic/less.py +1 -1
- maxframe/dataframe/arithmetic/less_equal.py +1 -1
- maxframe/dataframe/arithmetic/log.py +1 -1
- maxframe/dataframe/arithmetic/log10.py +1 -1
- maxframe/dataframe/arithmetic/log2.py +1 -1
- maxframe/dataframe/arithmetic/mod.py +1 -1
- maxframe/dataframe/arithmetic/multiply.py +1 -1
- maxframe/dataframe/arithmetic/negative.py +1 -1
- maxframe/dataframe/arithmetic/not_equal.py +1 -1
- maxframe/dataframe/arithmetic/power.py +1 -1
- maxframe/dataframe/arithmetic/radians.py +1 -1
- maxframe/dataframe/arithmetic/sin.py +1 -1
- maxframe/dataframe/arithmetic/sinh.py +1 -1
- maxframe/dataframe/arithmetic/sqrt.py +1 -1
- maxframe/dataframe/arithmetic/subtract.py +1 -1
- maxframe/dataframe/arithmetic/tan.py +1 -1
- maxframe/dataframe/arithmetic/tanh.py +1 -1
- maxframe/dataframe/arithmetic/tests/__init__.py +1 -1
- maxframe/dataframe/arithmetic/tests/test_arithmetic.py +1 -1
- maxframe/dataframe/arithmetic/truediv.py +1 -1
- maxframe/dataframe/arithmetic/trunc.py +1 -1
- maxframe/dataframe/arrays.py +1 -1
- maxframe/dataframe/core.py +1 -1
- maxframe/dataframe/datasource/__init__.py +1 -1
- maxframe/dataframe/datasource/core.py +1 -1
- maxframe/dataframe/datasource/dataframe.py +1 -1
- maxframe/dataframe/datasource/date_range.py +1 -1
- maxframe/dataframe/datasource/from_index.py +1 -1
- maxframe/dataframe/datasource/from_records.py +1 -1
- maxframe/dataframe/datasource/from_tensor.py +1 -1
- maxframe/dataframe/datasource/index.py +1 -1
- maxframe/dataframe/datasource/read_csv.py +1 -1
- maxframe/dataframe/datasource/read_odps_query.py +47 -17
- maxframe/dataframe/datasource/read_odps_table.py +5 -3
- maxframe/dataframe/datasource/read_parquet.py +1 -1
- maxframe/dataframe/datasource/series.py +1 -1
- maxframe/dataframe/datasource/tests/__init__.py +1 -1
- maxframe/dataframe/datasource/tests/test_datasource.py +55 -8
- maxframe/dataframe/datastore/__init__.py +1 -1
- maxframe/dataframe/datastore/core.py +1 -1
- maxframe/dataframe/datastore/tests/__init__.py +1 -1
- maxframe/dataframe/datastore/tests/test_to_odps.py +1 -1
- maxframe/dataframe/datastore/to_csv.py +1 -1
- maxframe/dataframe/datastore/to_odps.py +1 -1
- maxframe/dataframe/extensions/__init__.py +2 -2
- maxframe/dataframe/extensions/accessor.py +6 -22
- maxframe/dataframe/extensions/apply_chunk.py +86 -1
- maxframe/dataframe/extensions/flatjson.py +1 -1
- maxframe/dataframe/extensions/flatmap.py +1 -1
- maxframe/dataframe/extensions/reshuffle.py +1 -1
- maxframe/dataframe/extensions/tests/__init__.py +1 -1
- maxframe/dataframe/extensions/tests/test_apply_chunk.py +1 -1
- maxframe/dataframe/extensions/tests/test_extensions.py +1 -1
- maxframe/dataframe/fetch/__init__.py +1 -1
- maxframe/dataframe/fetch/core.py +1 -1
- maxframe/dataframe/groupby/__init__.py +1 -1
- maxframe/dataframe/groupby/aggregation.py +1 -1
- maxframe/dataframe/groupby/apply.py +1 -1
- maxframe/dataframe/groupby/core.py +1 -1
- maxframe/dataframe/groupby/cum.py +1 -1
- maxframe/dataframe/groupby/fill.py +1 -1
- maxframe/dataframe/groupby/getitem.py +1 -1
- maxframe/dataframe/groupby/head.py +1 -1
- maxframe/dataframe/groupby/sample.py +1 -1
- maxframe/dataframe/groupby/tests/__init__.py +1 -1
- maxframe/dataframe/groupby/tests/test_groupby.py +1 -1
- maxframe/dataframe/groupby/transform.py +1 -1
- maxframe/dataframe/indexing/__init__.py +1 -1
- maxframe/dataframe/indexing/add_prefix_suffix.py +1 -1
- maxframe/dataframe/indexing/align.py +1 -1
- maxframe/dataframe/indexing/at.py +1 -1
- maxframe/dataframe/indexing/getitem.py +1 -1
- maxframe/dataframe/indexing/iat.py +1 -1
- maxframe/dataframe/indexing/iloc.py +1 -1
- maxframe/dataframe/indexing/insert.py +1 -1
- maxframe/dataframe/indexing/loc.py +1 -1
- maxframe/dataframe/indexing/reindex.py +1 -1
- maxframe/dataframe/indexing/rename.py +1 -1
- maxframe/dataframe/indexing/rename_axis.py +1 -1
- maxframe/dataframe/indexing/reset_index.py +1 -1
- maxframe/dataframe/indexing/sample.py +1 -1
- maxframe/dataframe/indexing/set_axis.py +1 -1
- maxframe/dataframe/indexing/set_index.py +1 -1
- maxframe/dataframe/indexing/setitem.py +1 -1
- maxframe/dataframe/indexing/tests/__init__.py +1 -1
- maxframe/dataframe/indexing/tests/test_indexing.py +1 -1
- maxframe/dataframe/indexing/where.py +1 -1
- maxframe/dataframe/initializer.py +1 -1
- maxframe/dataframe/merge/__init__.py +1 -1
- maxframe/dataframe/merge/append.py +1 -1
- maxframe/dataframe/merge/concat.py +1 -1
- maxframe/dataframe/merge/merge.py +1 -1
- maxframe/dataframe/merge/tests/__init__.py +1 -1
- maxframe/dataframe/merge/tests/test_merge.py +1 -1
- maxframe/dataframe/misc/__init__.py +1 -16
- maxframe/dataframe/misc/_duplicate.py +1 -1
- maxframe/dataframe/misc/apply.py +74 -1
- maxframe/dataframe/misc/astype.py +1 -1
- maxframe/dataframe/misc/case_when.py +1 -1
- maxframe/dataframe/misc/check_monotonic.py +1 -1
- maxframe/dataframe/misc/cut.py +6 -4
- maxframe/dataframe/misc/describe.py +1 -1
- maxframe/dataframe/misc/diff.py +1 -1
- maxframe/dataframe/misc/drop.py +1 -1
- maxframe/dataframe/misc/drop_duplicates.py +7 -4
- maxframe/dataframe/misc/duplicated.py +1 -1
- maxframe/dataframe/misc/eval.py +1 -1
- maxframe/dataframe/misc/explode.py +1 -1
- maxframe/dataframe/misc/get_dummies.py +1 -1
- maxframe/dataframe/misc/isin.py +1 -1
- maxframe/dataframe/misc/map.py +1 -1
- maxframe/dataframe/misc/melt.py +1 -1
- maxframe/dataframe/misc/memory_usage.py +1 -1
- maxframe/dataframe/misc/pct_change.py +1 -1
- maxframe/dataframe/misc/pivot_table.py +1 -1
- maxframe/dataframe/misc/qcut.py +1 -1
- maxframe/dataframe/misc/select_dtypes.py +1 -1
- maxframe/dataframe/misc/shift.py +1 -1
- maxframe/dataframe/misc/stack.py +1 -1
- maxframe/dataframe/misc/tests/__init__.py +1 -1
- maxframe/dataframe/misc/tests/test_misc.py +1 -76
- maxframe/dataframe/misc/to_numeric.py +1 -1
- maxframe/dataframe/misc/transform.py +1 -1
- maxframe/dataframe/misc/transpose.py +1 -1
- maxframe/dataframe/misc/value_counts.py +1 -1
- maxframe/dataframe/missing/__init__.py +1 -1
- maxframe/dataframe/missing/checkna.py +1 -1
- maxframe/dataframe/missing/dropna.py +1 -1
- maxframe/dataframe/missing/fillna.py +1 -1
- maxframe/dataframe/missing/replace.py +1 -1
- maxframe/dataframe/missing/tests/__init__.py +1 -1
- maxframe/dataframe/missing/tests/test_missing.py +1 -1
- maxframe/dataframe/operators.py +1 -1
- maxframe/dataframe/reduction/__init__.py +1 -1
- maxframe/dataframe/reduction/aggregation.py +1 -1
- maxframe/dataframe/reduction/all.py +1 -1
- maxframe/dataframe/reduction/any.py +1 -1
- maxframe/dataframe/reduction/core.py +1 -1
- maxframe/dataframe/reduction/count.py +1 -1
- maxframe/dataframe/reduction/cummax.py +1 -1
- maxframe/dataframe/reduction/cummin.py +1 -1
- maxframe/dataframe/reduction/cumprod.py +1 -1
- maxframe/dataframe/reduction/cumsum.py +1 -1
- maxframe/dataframe/reduction/custom_reduction.py +1 -1
- maxframe/dataframe/reduction/kurtosis.py +1 -1
- maxframe/dataframe/reduction/max.py +1 -1
- maxframe/dataframe/reduction/mean.py +1 -1
- maxframe/dataframe/reduction/median.py +1 -1
- maxframe/dataframe/reduction/min.py +1 -1
- maxframe/dataframe/reduction/nunique.py +1 -1
- maxframe/dataframe/reduction/prod.py +1 -1
- maxframe/dataframe/reduction/reduction_size.py +1 -1
- maxframe/dataframe/reduction/sem.py +1 -1
- maxframe/dataframe/reduction/skew.py +1 -1
- maxframe/dataframe/reduction/std.py +1 -1
- maxframe/dataframe/reduction/str_concat.py +1 -1
- maxframe/dataframe/reduction/sum.py +1 -1
- maxframe/dataframe/reduction/tests/__init__.py +1 -1
- maxframe/dataframe/reduction/tests/test_reduction.py +1 -1
- maxframe/dataframe/reduction/unique.py +1 -1
- maxframe/dataframe/reduction/var.py +1 -1
- maxframe/dataframe/sort/__init__.py +1 -1
- maxframe/dataframe/sort/core.py +1 -1
- maxframe/dataframe/sort/sort_index.py +1 -1
- maxframe/dataframe/sort/sort_values.py +1 -1
- maxframe/dataframe/sort/tests/__init__.py +1 -1
- maxframe/dataframe/sort/tests/test_sort.py +1 -1
- maxframe/dataframe/statistics/__init__.py +1 -1
- maxframe/dataframe/statistics/corr.py +1 -1
- maxframe/dataframe/statistics/quantile.py +1 -1
- maxframe/dataframe/statistics/tests/__init__.py +1 -1
- maxframe/dataframe/statistics/tests/test_statistics.py +1 -1
- maxframe/dataframe/tests/__init__.py +1 -1
- maxframe/dataframe/tests/test_initializer.py +1 -1
- maxframe/dataframe/tests/test_utils.py +36 -2
- maxframe/dataframe/tseries/__init__.py +1 -1
- maxframe/dataframe/tseries/tests/__init__.py +1 -1
- maxframe/dataframe/tseries/tests/test_tseries.py +1 -1
- maxframe/dataframe/tseries/to_datetime.py +1 -1
- maxframe/dataframe/ufunc/__init__.py +1 -1
- maxframe/dataframe/ufunc/tensor.py +1 -1
- maxframe/dataframe/ufunc/ufunc.py +1 -1
- maxframe/dataframe/utils.py +22 -2
- maxframe/dataframe/window/__init__.py +1 -1
- maxframe/dataframe/window/aggregation.py +1 -1
- maxframe/dataframe/window/core.py +1 -1
- maxframe/dataframe/window/ewm.py +1 -1
- maxframe/dataframe/window/expanding.py +1 -1
- maxframe/dataframe/window/rolling.py +1 -1
- maxframe/dataframe/window/tests/__init__.py +1 -1
- maxframe/dataframe/window/tests/test_ewm.py +1 -1
- maxframe/dataframe/window/tests/test_expanding.py +1 -1
- maxframe/dataframe/window/tests/test_rolling.py +1 -1
- maxframe/env.py +1 -1
- maxframe/errors.py +5 -1
- maxframe/extension.py +5 -2
- maxframe/io/__init__.py +1 -1
- maxframe/io/objects/__init__.py +1 -1
- maxframe/io/objects/core.py +1 -1
- maxframe/io/objects/tensor.py +1 -1
- maxframe/io/objects/tests/__init__.py +1 -1
- maxframe/io/objects/tests/test_object_io.py +1 -1
- maxframe/io/odpsio/__init__.py +2 -2
- maxframe/io/odpsio/arrow.py +29 -4
- maxframe/io/odpsio/schema.py +75 -3
- maxframe/io/odpsio/tableio.py +66 -20
- maxframe/io/odpsio/tests/__init__.py +1 -1
- maxframe/io/odpsio/tests/test_arrow.py +46 -1
- maxframe/io/odpsio/tests/test_schema.py +19 -1
- maxframe/io/odpsio/tests/test_tableio.py +1 -1
- maxframe/io/odpsio/tests/test_volumeio.py +1 -1
- maxframe/io/odpsio/volumeio.py +1 -1
- maxframe/learn/__init__.py +1 -1
- maxframe/learn/contrib/__init__.py +1 -1
- maxframe/learn/contrib/graph/__init__.py +1 -1
- maxframe/learn/contrib/graph/connected_components.py +1 -1
- maxframe/learn/contrib/graph/tests/__init__.py +1 -1
- maxframe/learn/contrib/graph/tests/test_connected_components.py +1 -1
- maxframe/learn/contrib/llm/__init__.py +1 -1
- maxframe/learn/contrib/llm/core.py +1 -1
- maxframe/learn/contrib/llm/models/__init__.py +1 -1
- maxframe/learn/contrib/llm/models/dashscope.py +1 -1
- maxframe/learn/contrib/llm/multi_modal.py +1 -1
- maxframe/learn/contrib/llm/text.py +1 -1
- maxframe/learn/contrib/pytorch/__init__.py +1 -1
- maxframe/learn/contrib/pytorch/run_function.py +1 -1
- maxframe/learn/contrib/pytorch/run_script.py +1 -1
- maxframe/learn/contrib/pytorch/tests/__init__.py +1 -1
- maxframe/learn/contrib/pytorch/tests/test_pytorch.py +1 -1
- maxframe/learn/contrib/utils.py +1 -1
- maxframe/learn/contrib/xgboost/__init__.py +1 -1
- maxframe/learn/contrib/xgboost/classifier.py +1 -1
- maxframe/learn/contrib/xgboost/core.py +1 -1
- maxframe/learn/contrib/xgboost/dmatrix.py +5 -2
- maxframe/learn/contrib/xgboost/predict.py +1 -1
- maxframe/learn/contrib/xgboost/regressor.py +1 -1
- maxframe/learn/contrib/xgboost/tests/__init__.py +1 -1
- maxframe/learn/contrib/xgboost/tests/test_core.py +1 -1
- maxframe/learn/contrib/xgboost/train.py +1 -1
- maxframe/learn/core.py +1 -1
- maxframe/learn/utils/__init__.py +1 -1
- maxframe/learn/utils/core.py +1 -1
- maxframe/lib/__init__.py +1 -1
- maxframe/lib/aio/__init__.py +1 -1
- maxframe/lib/aio/_runners.py +1 -1
- maxframe/lib/aio/_threads.py +1 -1
- maxframe/lib/aio/base.py +1 -1
- maxframe/lib/aio/file.py +1 -1
- maxframe/lib/aio/isolation.py +1 -1
- maxframe/lib/aio/lru.py +1 -1
- maxframe/lib/aio/parallelism.py +1 -1
- maxframe/lib/aio/tests/__init__.py +1 -1
- maxframe/lib/aio/tests/test_aio_file.py +1 -1
- maxframe/lib/compression.py +1 -1
- maxframe/lib/cython/__init__.py +1 -1
- maxframe/lib/cython/libcpp.pxd +1 -1
- maxframe/lib/dtypes_extension/__init__.py +14 -0
- maxframe/lib/dtypes_extension/dtypes.py +91 -0
- maxframe/lib/dtypes_extension/tests/__init__.py +13 -0
- maxframe/lib/dtypes_extension/tests/test_dtypes.py +68 -0
- maxframe/lib/filesystem/__init__.py +1 -1
- maxframe/lib/filesystem/_glob.py +1 -1
- maxframe/lib/filesystem/_oss_lib/__init__.py +1 -1
- maxframe/lib/filesystem/_oss_lib/common.py +1 -1
- maxframe/lib/filesystem/_oss_lib/glob.py +1 -1
- maxframe/lib/filesystem/_oss_lib/handle.py +1 -1
- maxframe/lib/filesystem/arrow.py +1 -1
- maxframe/lib/filesystem/base.py +1 -1
- maxframe/lib/filesystem/core.py +1 -1
- maxframe/lib/filesystem/fsmap.py +1 -1
- maxframe/lib/filesystem/hdfs.py +1 -1
- maxframe/lib/filesystem/local.py +1 -1
- maxframe/lib/filesystem/oss.py +1 -1
- maxframe/lib/filesystem/tests/__init__.py +1 -1
- maxframe/lib/filesystem/tests/test_filesystem.py +6 -4
- maxframe/lib/filesystem/tests/test_oss.py +1 -1
- maxframe/lib/functools_compat.py +1 -1
- maxframe/lib/mmh3.cp311-win_amd64.pyd +0 -0
- maxframe/lib/mmh3.pyi +1 -1
- maxframe/lib/sparse/__init__.py +1 -1
- maxframe/lib/sparse/array.py +1 -1
- maxframe/lib/sparse/core.py +1 -1
- maxframe/lib/sparse/matrix.py +1 -1
- maxframe/lib/sparse/tests/__init__.py +1 -1
- maxframe/lib/sparse/tests/test_sparse.py +1 -1
- maxframe/lib/sparse/vector.py +1 -1
- maxframe/lib/tests/__init__.py +1 -1
- maxframe/lib/tests/test_wrapped_pickle.py +1 -1
- maxframe/lib/version.py +1 -1
- maxframe/lib/wrapped_pickle.py +1 -1
- maxframe/mixin.py +1 -1
- maxframe/opcodes.py +6 -1
- maxframe/protocol.py +1 -1
- maxframe/remote/__init__.py +1 -1
- maxframe/remote/core.py +1 -1
- maxframe/remote/run_script.py +1 -1
- maxframe/serialization/__init__.py +1 -1
- maxframe/serialization/arrow.py +1 -1
- maxframe/serialization/core.cp311-win_amd64.pyd +0 -0
- maxframe/serialization/core.pxd +1 -1
- maxframe/serialization/core.pyi +1 -1
- maxframe/serialization/core.pyx +9 -6
- maxframe/serialization/exception.py +1 -1
- maxframe/serialization/maxframe_objects.py +1 -1
- maxframe/serialization/numpy.py +1 -1
- maxframe/serialization/pandas.py +1 -1
- maxframe/serialization/scipy.py +1 -1
- maxframe/serialization/serializables/__init__.py +1 -1
- maxframe/serialization/serializables/core.py +128 -87
- maxframe/serialization/serializables/field.py +1 -1
- maxframe/serialization/serializables/field_type.py +1 -1
- maxframe/serialization/serializables/tests/__init__.py +1 -1
- maxframe/serialization/serializables/tests/test_field_type.py +1 -1
- maxframe/serialization/serializables/tests/test_serializable.py +5 -2
- maxframe/serialization/tests/__init__.py +1 -1
- maxframe/serialization/tests/test_serial.py +21 -3
- maxframe/session.py +1 -1
- maxframe/tensor/__init__.py +1 -1
- maxframe/tensor/arithmetic/__init__.py +1 -1
- maxframe/tensor/arithmetic/abs.py +1 -1
- maxframe/tensor/arithmetic/absolute.py +1 -1
- maxframe/tensor/arithmetic/add.py +1 -1
- maxframe/tensor/arithmetic/angle.py +1 -1
- maxframe/tensor/arithmetic/arccos.py +1 -1
- maxframe/tensor/arithmetic/arccosh.py +1 -1
- maxframe/tensor/arithmetic/arcsin.py +1 -1
- maxframe/tensor/arithmetic/arcsinh.py +1 -1
- maxframe/tensor/arithmetic/arctan.py +1 -1
- maxframe/tensor/arithmetic/arctan2.py +1 -1
- maxframe/tensor/arithmetic/arctanh.py +1 -1
- maxframe/tensor/arithmetic/around.py +1 -1
- maxframe/tensor/arithmetic/bitand.py +1 -1
- maxframe/tensor/arithmetic/bitor.py +1 -1
- maxframe/tensor/arithmetic/bitxor.py +1 -1
- maxframe/tensor/arithmetic/cbrt.py +1 -1
- maxframe/tensor/arithmetic/ceil.py +1 -1
- maxframe/tensor/arithmetic/clip.py +1 -1
- maxframe/tensor/arithmetic/conj.py +1 -1
- maxframe/tensor/arithmetic/copysign.py +1 -1
- maxframe/tensor/arithmetic/core.py +1 -1
- maxframe/tensor/arithmetic/cos.py +1 -1
- maxframe/tensor/arithmetic/cosh.py +1 -1
- maxframe/tensor/arithmetic/deg2rad.py +1 -1
- maxframe/tensor/arithmetic/degrees.py +1 -1
- maxframe/tensor/arithmetic/divide.py +1 -1
- maxframe/tensor/arithmetic/equal.py +1 -1
- maxframe/tensor/arithmetic/exp.py +1 -1
- maxframe/tensor/arithmetic/exp2.py +1 -1
- maxframe/tensor/arithmetic/expm1.py +1 -1
- maxframe/tensor/arithmetic/fabs.py +1 -1
- maxframe/tensor/arithmetic/fix.py +1 -1
- maxframe/tensor/arithmetic/float_power.py +1 -1
- maxframe/tensor/arithmetic/floor.py +1 -1
- maxframe/tensor/arithmetic/floordiv.py +1 -1
- maxframe/tensor/arithmetic/fmax.py +1 -1
- maxframe/tensor/arithmetic/fmin.py +1 -1
- maxframe/tensor/arithmetic/fmod.py +1 -1
- maxframe/tensor/arithmetic/frexp.py +1 -1
- maxframe/tensor/arithmetic/greater.py +1 -1
- maxframe/tensor/arithmetic/greater_equal.py +1 -1
- maxframe/tensor/arithmetic/hypot.py +1 -1
- maxframe/tensor/arithmetic/i0.py +1 -1
- maxframe/tensor/arithmetic/imag.py +1 -1
- maxframe/tensor/arithmetic/invert.py +1 -1
- maxframe/tensor/arithmetic/isclose.py +1 -1
- maxframe/tensor/arithmetic/iscomplex.py +1 -1
- maxframe/tensor/arithmetic/isfinite.py +1 -1
- maxframe/tensor/arithmetic/isinf.py +1 -1
- maxframe/tensor/arithmetic/isnan.py +1 -1
- maxframe/tensor/arithmetic/isreal.py +1 -1
- maxframe/tensor/arithmetic/ldexp.py +1 -1
- maxframe/tensor/arithmetic/less.py +1 -1
- maxframe/tensor/arithmetic/less_equal.py +1 -1
- maxframe/tensor/arithmetic/log.py +1 -1
- maxframe/tensor/arithmetic/log10.py +1 -1
- maxframe/tensor/arithmetic/log1p.py +1 -1
- maxframe/tensor/arithmetic/log2.py +1 -1
- maxframe/tensor/arithmetic/logaddexp.py +1 -1
- maxframe/tensor/arithmetic/logaddexp2.py +1 -1
- maxframe/tensor/arithmetic/logical_and.py +1 -1
- maxframe/tensor/arithmetic/logical_not.py +1 -1
- maxframe/tensor/arithmetic/logical_or.py +1 -1
- maxframe/tensor/arithmetic/logical_xor.py +1 -1
- maxframe/tensor/arithmetic/lshift.py +1 -1
- maxframe/tensor/arithmetic/maximum.py +1 -1
- maxframe/tensor/arithmetic/minimum.py +1 -1
- maxframe/tensor/arithmetic/mod.py +1 -1
- maxframe/tensor/arithmetic/modf.py +1 -1
- maxframe/tensor/arithmetic/multiply.py +1 -1
- maxframe/tensor/arithmetic/nan_to_num.py +1 -1
- maxframe/tensor/arithmetic/negative.py +1 -1
- maxframe/tensor/arithmetic/nextafter.py +1 -1
- maxframe/tensor/arithmetic/not_equal.py +1 -1
- maxframe/tensor/arithmetic/positive.py +1 -1
- maxframe/tensor/arithmetic/power.py +1 -1
- maxframe/tensor/arithmetic/rad2deg.py +1 -1
- maxframe/tensor/arithmetic/radians.py +1 -1
- maxframe/tensor/arithmetic/real.py +1 -1
- maxframe/tensor/arithmetic/reciprocal.py +1 -1
- maxframe/tensor/arithmetic/rint.py +1 -1
- maxframe/tensor/arithmetic/rshift.py +1 -1
- maxframe/tensor/arithmetic/setimag.py +1 -1
- maxframe/tensor/arithmetic/setreal.py +1 -1
- maxframe/tensor/arithmetic/sign.py +1 -1
- maxframe/tensor/arithmetic/signbit.py +1 -1
- maxframe/tensor/arithmetic/sin.py +1 -1
- maxframe/tensor/arithmetic/sinc.py +1 -1
- maxframe/tensor/arithmetic/sinh.py +1 -1
- maxframe/tensor/arithmetic/spacing.py +1 -1
- maxframe/tensor/arithmetic/sqrt.py +1 -1
- maxframe/tensor/arithmetic/square.py +1 -1
- maxframe/tensor/arithmetic/subtract.py +1 -1
- maxframe/tensor/arithmetic/tan.py +1 -1
- maxframe/tensor/arithmetic/tanh.py +1 -1
- maxframe/tensor/arithmetic/tests/__init__.py +1 -1
- maxframe/tensor/arithmetic/tests/test_arithmetic.py +1 -1
- maxframe/tensor/arithmetic/truediv.py +1 -1
- maxframe/tensor/arithmetic/trunc.py +1 -1
- maxframe/tensor/arithmetic/utils.py +1 -1
- maxframe/tensor/array_utils.py +1 -1
- maxframe/tensor/core.py +1 -1
- maxframe/tensor/datasource/__init__.py +1 -1
- maxframe/tensor/datasource/arange.py +1 -1
- maxframe/tensor/datasource/array.py +1 -1
- maxframe/tensor/datasource/core.py +1 -1
- maxframe/tensor/datasource/empty.py +1 -1
- maxframe/tensor/datasource/from_dataframe.py +1 -1
- maxframe/tensor/datasource/from_dense.py +1 -1
- maxframe/tensor/datasource/from_sparse.py +1 -1
- maxframe/tensor/datasource/full.py +1 -1
- maxframe/tensor/datasource/ones.py +1 -1
- maxframe/tensor/datasource/scalar.py +1 -1
- maxframe/tensor/datasource/tests/__init__.py +1 -1
- maxframe/tensor/datasource/tests/test_datasource.py +1 -1
- maxframe/tensor/datasource/zeros.py +1 -1
- maxframe/tensor/fetch/__init__.py +1 -1
- maxframe/tensor/fetch/core.py +1 -1
- maxframe/tensor/indexing/__init__.py +1 -1
- maxframe/tensor/indexing/choose.py +1 -1
- maxframe/tensor/indexing/compress.py +1 -1
- maxframe/tensor/indexing/core.py +1 -1
- maxframe/tensor/indexing/extract.py +1 -1
- maxframe/tensor/indexing/fill_diagonal.py +1 -1
- maxframe/tensor/indexing/flatnonzero.py +1 -1
- maxframe/tensor/indexing/getitem.py +1 -1
- maxframe/tensor/indexing/nonzero.py +1 -1
- maxframe/tensor/indexing/setitem.py +1 -1
- maxframe/tensor/indexing/slice.py +1 -1
- maxframe/tensor/indexing/take.py +1 -1
- maxframe/tensor/indexing/tests/__init__.py +1 -1
- maxframe/tensor/indexing/tests/test_indexing.py +1 -1
- maxframe/tensor/indexing/unravel_index.py +1 -1
- maxframe/tensor/merge/__init__.py +1 -1
- maxframe/tensor/merge/concatenate.py +1 -1
- maxframe/tensor/merge/stack.py +1 -1
- maxframe/tensor/merge/tests/__init__.py +1 -1
- maxframe/tensor/merge/tests/test_merge.py +1 -1
- maxframe/tensor/merge/vstack.py +2 -2
- maxframe/tensor/misc/__init__.py +1 -1
- maxframe/tensor/misc/astype.py +1 -1
- maxframe/tensor/misc/atleast_1d.py +1 -1
- maxframe/tensor/misc/atleast_2d.py +1 -1
- maxframe/tensor/misc/atleast_3d.py +1 -1
- maxframe/tensor/misc/broadcast_to.py +1 -1
- maxframe/tensor/misc/ravel.py +1 -1
- maxframe/tensor/misc/tests/__init__.py +1 -1
- maxframe/tensor/misc/tests/test_misc.py +1 -1
- maxframe/tensor/misc/transpose.py +1 -1
- maxframe/tensor/misc/unique.py +1 -1
- maxframe/tensor/misc/where.py +1 -1
- maxframe/tensor/operators.py +1 -1
- maxframe/tensor/random/__init__.py +1 -1
- maxframe/tensor/random/beta.py +1 -1
- maxframe/tensor/random/binomial.py +1 -1
- maxframe/tensor/random/bytes.py +1 -1
- maxframe/tensor/random/chisquare.py +1 -1
- maxframe/tensor/random/choice.py +1 -1
- maxframe/tensor/random/core.py +1 -1
- maxframe/tensor/random/dirichlet.py +1 -1
- maxframe/tensor/random/exponential.py +1 -1
- maxframe/tensor/random/f.py +1 -1
- maxframe/tensor/random/gamma.py +1 -1
- maxframe/tensor/random/geometric.py +1 -1
- maxframe/tensor/random/gumbel.py +1 -1
- maxframe/tensor/random/hypergeometric.py +1 -1
- maxframe/tensor/random/laplace.py +1 -1
- maxframe/tensor/random/logistic.py +1 -1
- maxframe/tensor/random/lognormal.py +1 -1
- maxframe/tensor/random/logseries.py +1 -1
- maxframe/tensor/random/multinomial.py +1 -1
- maxframe/tensor/random/multivariate_normal.py +1 -1
- maxframe/tensor/random/negative_binomial.py +1 -1
- maxframe/tensor/random/noncentral_chisquare.py +1 -1
- maxframe/tensor/random/noncentral_f.py +1 -1
- maxframe/tensor/random/normal.py +1 -1
- maxframe/tensor/random/pareto.py +1 -1
- maxframe/tensor/random/permutation.py +1 -1
- maxframe/tensor/random/poisson.py +1 -1
- maxframe/tensor/random/power.py +1 -1
- maxframe/tensor/random/rand.py +1 -1
- maxframe/tensor/random/randint.py +1 -1
- maxframe/tensor/random/randn.py +1 -1
- maxframe/tensor/random/random_integers.py +1 -1
- maxframe/tensor/random/random_sample.py +1 -1
- maxframe/tensor/random/rayleigh.py +1 -1
- maxframe/tensor/random/shuffle.py +1 -1
- maxframe/tensor/random/standard_cauchy.py +1 -1
- maxframe/tensor/random/standard_exponential.py +1 -1
- maxframe/tensor/random/standard_gamma.py +1 -1
- maxframe/tensor/random/standard_normal.py +1 -1
- maxframe/tensor/random/standard_t.py +1 -1
- maxframe/tensor/random/tests/__init__.py +1 -1
- maxframe/tensor/random/tests/test_random.py +1 -1
- maxframe/tensor/random/triangular.py +1 -1
- maxframe/tensor/random/uniform.py +1 -1
- maxframe/tensor/random/vonmises.py +1 -1
- maxframe/tensor/random/wald.py +1 -1
- maxframe/tensor/random/weibull.py +1 -1
- maxframe/tensor/random/zipf.py +1 -1
- maxframe/tensor/rechunk/__init__.py +1 -1
- maxframe/tensor/rechunk/rechunk.py +1 -1
- maxframe/tensor/reduction/__init__.py +1 -1
- maxframe/tensor/reduction/all.py +1 -1
- maxframe/tensor/reduction/allclose.py +1 -1
- maxframe/tensor/reduction/any.py +1 -1
- maxframe/tensor/reduction/argmax.py +1 -1
- maxframe/tensor/reduction/argmin.py +1 -1
- maxframe/tensor/reduction/array_equal.py +1 -1
- maxframe/tensor/reduction/core.py +1 -1
- maxframe/tensor/reduction/count_nonzero.py +1 -1
- maxframe/tensor/reduction/cumprod.py +1 -1
- maxframe/tensor/reduction/cumsum.py +1 -1
- maxframe/tensor/reduction/max.py +1 -1
- maxframe/tensor/reduction/mean.py +1 -1
- maxframe/tensor/reduction/min.py +1 -1
- maxframe/tensor/reduction/nanargmax.py +1 -1
- maxframe/tensor/reduction/nanargmin.py +1 -1
- maxframe/tensor/reduction/nancumprod.py +1 -1
- maxframe/tensor/reduction/nancumsum.py +1 -1
- maxframe/tensor/reduction/nanmax.py +1 -1
- maxframe/tensor/reduction/nanmean.py +1 -1
- maxframe/tensor/reduction/nanmin.py +1 -1
- maxframe/tensor/reduction/nanprod.py +1 -1
- maxframe/tensor/reduction/nanstd.py +1 -1
- maxframe/tensor/reduction/nansum.py +1 -1
- maxframe/tensor/reduction/nanvar.py +1 -1
- maxframe/tensor/reduction/prod.py +1 -1
- maxframe/tensor/reduction/std.py +1 -1
- maxframe/tensor/reduction/sum.py +1 -1
- maxframe/tensor/reduction/tests/__init__.py +1 -1
- maxframe/tensor/reduction/tests/test_reduction.py +1 -1
- maxframe/tensor/reduction/var.py +1 -1
- maxframe/tensor/reshape/__init__.py +1 -1
- maxframe/tensor/reshape/reshape.py +1 -1
- maxframe/tensor/reshape/tests/__init__.py +1 -1
- maxframe/tensor/reshape/tests/test_reshape.py +1 -1
- maxframe/tensor/statistics/__init__.py +1 -1
- maxframe/tensor/statistics/percentile.py +1 -1
- maxframe/tensor/statistics/quantile.py +1 -1
- maxframe/tensor/ufunc/__init__.py +1 -1
- maxframe/tensor/ufunc/ufunc.py +1 -1
- maxframe/tensor/utils.py +1 -1
- maxframe/tests/__init__.py +1 -1
- maxframe/tests/test_codegen.py +1 -1
- maxframe/tests/test_protocol.py +1 -1
- maxframe/tests/test_utils.py +1 -1
- maxframe/tests/utils.py +1 -1
- maxframe/typing_.py +1 -1
- maxframe/udf.py +6 -1
- maxframe/utils.py +14 -1
- {maxframe-1.1.0.dist-info → maxframe-1.2.0.dist-info}/METADATA +5 -4
- maxframe-1.2.0.dist-info/RECORD +697 -0
- {maxframe-1.1.0.dist-info → maxframe-1.2.0.dist-info}/WHEEL +1 -1
- maxframe_client/__init__.py +1 -1
- maxframe_client/clients/__init__.py +1 -1
- maxframe_client/clients/framedriver.py +1 -1
- maxframe_client/conftest.py +1 -1
- maxframe_client/fetcher.py +6 -7
- maxframe_client/session/__init__.py +1 -1
- maxframe_client/session/consts.py +1 -1
- maxframe_client/session/graph.py +1 -1
- maxframe_client/session/odps.py +19 -2
- maxframe_client/session/task.py +5 -2
- maxframe_client/session/tests/__init__.py +1 -1
- maxframe_client/session/tests/test_task.py +36 -3
- maxframe_client/tests/__init__.py +1 -1
- maxframe_client/tests/test_fetcher.py +1 -1
- maxframe_client/tests/test_session.py +1 -1
- maxframe-1.1.0.dist-info/RECORD +0 -675
- {maxframe-1.1.0.dist-info → maxframe-1.2.0.dist-info}/top_level.txt +0 -0
maxframe/serialization/arrow.py
CHANGED
|
Binary file
|
maxframe/serialization/core.pxd
CHANGED
maxframe/serialization/core.pyi
CHANGED
maxframe/serialization/core.pyx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# distutils: language = c++
|
|
2
|
-
# Copyright 1999-
|
|
2
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
3
3
|
#
|
|
4
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
# you may not use this file except in compliance with the License.
|
|
@@ -37,13 +37,9 @@ from .._utils import NamedType
|
|
|
37
37
|
from .._utils cimport TypeDispatcher
|
|
38
38
|
|
|
39
39
|
from ..lib import wrapped_pickle as pickle
|
|
40
|
+
from ..lib.dtypes_extension import ArrowDtype
|
|
40
41
|
from ..utils import NoDefault, arrow_type_from_str, no_default
|
|
41
42
|
|
|
42
|
-
try:
|
|
43
|
-
from pandas import ArrowDtype
|
|
44
|
-
except ImportError:
|
|
45
|
-
ArrowDtype = type(None)
|
|
46
|
-
|
|
47
43
|
# resolve pandas pickle compatibility between <1.2 and >=1.3
|
|
48
44
|
try:
|
|
49
45
|
from pandas.core.internals import blocks as pd_blocks
|
|
@@ -67,6 +63,7 @@ except ImportError:
|
|
|
67
63
|
BUFFER_PICKLE_PROTOCOL = max(pickle.DEFAULT_PROTOCOL, 5)
|
|
68
64
|
cdef bint HAS_PICKLE_BUFFER = pickle.HIGHEST_PROTOCOL >= 5
|
|
69
65
|
cdef bint _PANDAS_HAS_MGR = hasattr(pd.Series([0]), "_mgr")
|
|
66
|
+
cdef bint _ARROW_DTYPE_NOT_SUPPORTED = ArrowDtype is None
|
|
70
67
|
|
|
71
68
|
|
|
72
69
|
cdef TypeDispatcher _serial_dispatcher = TypeDispatcher()
|
|
@@ -728,6 +725,8 @@ cdef class DtypeSerializer(Serializer):
|
|
|
728
725
|
dtype_new_order = list(fields)
|
|
729
726
|
return [_TYPE_CHAR_DTYPE_NUMPY, desc, dtype_new_order], [], True
|
|
730
727
|
elif isinstance(obj, ExtensionDtype):
|
|
728
|
+
if _ARROW_DTYPE_NOT_SUPPORTED:
|
|
729
|
+
raise ImportError("ArrowDtype is not supported in current environment")
|
|
731
730
|
if isinstance(obj, ArrowDtype):
|
|
732
731
|
return [_TYPE_CHAR_DTYPE_PANDAS_ARROW, str(obj.pyarrow_dtype)], [], True
|
|
733
732
|
elif isinstance(obj, pd.CategoricalDtype):
|
|
@@ -756,12 +755,16 @@ cdef class DtypeSerializer(Serializer):
|
|
|
756
755
|
dt = dt[serialized[2]]
|
|
757
756
|
return dt
|
|
758
757
|
elif ser_type == _TYPE_CHAR_DTYPE_PANDAS_ARROW:
|
|
758
|
+
if _ARROW_DTYPE_NOT_SUPPORTED:
|
|
759
|
+
raise ImportError("ArrowDtype is not supported in current environment")
|
|
759
760
|
return ArrowDtype(arrow_type_from_str(serialized[1]))
|
|
760
761
|
elif ser_type == _TYPE_CHAR_DTYPE_PANDAS_CATEGORICAL:
|
|
761
762
|
return pd.CategoricalDtype(subs[0], serialized[1])
|
|
762
763
|
elif ser_type == _TYPE_CHAR_DTYPE_PANDAS_INTERVAL:
|
|
763
764
|
return pd.IntervalDtype(subs[0], serialized[1])
|
|
764
765
|
elif ser_type == _TYPE_CHAR_DTYPE_PANDAS_EXTENSION:
|
|
766
|
+
if serialized[1] == "StringDtype": # for legacy pandas version
|
|
767
|
+
return pd.StringDtype()
|
|
765
768
|
return pandas_dtype(serialized[1])
|
|
766
769
|
else:
|
|
767
770
|
raise NotImplementedError(f"Unknown serialization type {ser_type}")
|
maxframe/serialization/numpy.py
CHANGED
maxframe/serialization/pandas.py
CHANGED
maxframe/serialization/scipy.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 1999-
|
|
1
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -12,18 +12,28 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
import logging
|
|
15
16
|
import weakref
|
|
16
|
-
from collections import
|
|
17
|
+
from collections import OrderedDict
|
|
17
18
|
from typing import Any, Dict, List, Optional, Tuple, Type
|
|
18
19
|
|
|
19
20
|
import msgpack
|
|
20
21
|
|
|
22
|
+
from ...errors import MaxFrameDeprecationError
|
|
21
23
|
from ...lib.mmh3 import hash
|
|
22
24
|
from ...utils import no_default
|
|
23
25
|
from ..core import Placeholder, Serializer, buffered, load_type
|
|
24
26
|
from .field import Field
|
|
25
27
|
from .field_type import DictType, ListType, PrimitiveFieldType, TupleType
|
|
26
28
|
|
|
29
|
+
try:
|
|
30
|
+
from ..deserializer import get_legacy_module_name
|
|
31
|
+
except ImportError:
|
|
32
|
+
get_legacy_module_name = lambda x: x
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
_deprecate_log_key = "_SER_DEPRECATE_LOGGED"
|
|
36
|
+
|
|
27
37
|
|
|
28
38
|
def _is_field_primitive_compound(field: Field):
|
|
29
39
|
if field.on_serialize is not None or field.on_deserialize is not None:
|
|
@@ -52,19 +62,24 @@ def _is_field_primitive_compound(field: Field):
|
|
|
52
62
|
class SerializableMeta(type):
|
|
53
63
|
def __new__(mcs, name: str, bases: Tuple[Type], properties: Dict):
|
|
54
64
|
# All the fields including misc fields.
|
|
55
|
-
legacy_name_hash = hash(
|
|
65
|
+
legacy_name_hash = hash(
|
|
66
|
+
f"{get_legacy_module_name(properties.get('__module__'))}.{name}"
|
|
67
|
+
)
|
|
56
68
|
name_hash = hash(
|
|
57
69
|
f"{properties.get('__module__')}.{properties.get('__qualname__')}"
|
|
58
70
|
)
|
|
59
71
|
all_fields = dict()
|
|
60
72
|
# mapping field names to base classes
|
|
61
73
|
field_to_cls_hash = dict()
|
|
74
|
+
# mapping legacy name hash to name hashes
|
|
75
|
+
legacy_to_new_name_hash = {legacy_name_hash: name_hash}
|
|
62
76
|
|
|
63
77
|
for base in bases:
|
|
64
78
|
if not hasattr(base, "_FIELDS"):
|
|
65
79
|
continue
|
|
66
80
|
all_fields.update(base._FIELDS)
|
|
67
81
|
field_to_cls_hash.update(base._FIELD_TO_NAME_HASH)
|
|
82
|
+
legacy_to_new_name_hash.update(base._LEGACY_TO_NEW_NAME_HASH)
|
|
68
83
|
|
|
69
84
|
properties_without_fields = {}
|
|
70
85
|
properties_field_slot_names = []
|
|
@@ -98,14 +113,18 @@ class SerializableMeta(type):
|
|
|
98
113
|
non_primitive_fields.append(v)
|
|
99
114
|
|
|
100
115
|
# count number of fields for every base class
|
|
101
|
-
cls_to_primitive_field_count =
|
|
102
|
-
cls_to_non_primitive_field_count =
|
|
116
|
+
cls_to_primitive_field_count = OrderedDict()
|
|
117
|
+
cls_to_non_primitive_field_count = OrderedDict()
|
|
103
118
|
for field_name in field_order:
|
|
104
119
|
cls_hash = field_to_cls_hash[field_name]
|
|
105
120
|
if field_name in primitive_field_names:
|
|
106
|
-
cls_to_primitive_field_count[cls_hash]
|
|
121
|
+
cls_to_primitive_field_count[cls_hash] = (
|
|
122
|
+
cls_to_primitive_field_count.get(cls_hash, 0) + 1
|
|
123
|
+
)
|
|
107
124
|
else:
|
|
108
|
-
cls_to_non_primitive_field_count[cls_hash]
|
|
125
|
+
cls_to_non_primitive_field_count[cls_hash] = (
|
|
126
|
+
cls_to_non_primitive_field_count.get(cls_hash, 0) + 1
|
|
127
|
+
)
|
|
109
128
|
|
|
110
129
|
slots = set(properties.pop("__slots__", set()))
|
|
111
130
|
slots.update(properties_field_slot_names)
|
|
@@ -114,15 +133,18 @@ class SerializableMeta(type):
|
|
|
114
133
|
|
|
115
134
|
# todo remove this prop when all versions below v1.0.0rc1 is eliminated
|
|
116
135
|
properties["_LEGACY_NAME_HASH"] = legacy_name_hash
|
|
117
|
-
|
|
118
136
|
properties["_NAME_HASH"] = name_hash
|
|
137
|
+
properties["_LEGACY_TO_NEW_NAME_HASH"] = legacy_to_new_name_hash
|
|
138
|
+
|
|
119
139
|
properties["_FIELDS"] = all_fields
|
|
120
140
|
properties["_FIELD_ORDER"] = field_order
|
|
121
141
|
properties["_FIELD_TO_NAME_HASH"] = field_to_cls_hash
|
|
122
142
|
properties["_PRIMITIVE_FIELDS"] = primitive_fields
|
|
123
|
-
properties["_CLS_TO_PRIMITIVE_FIELD_COUNT"] =
|
|
143
|
+
properties["_CLS_TO_PRIMITIVE_FIELD_COUNT"] = OrderedDict(
|
|
144
|
+
cls_to_primitive_field_count
|
|
145
|
+
)
|
|
124
146
|
properties["_NON_PRIMITIVE_FIELDS"] = non_primitive_fields
|
|
125
|
-
properties["_CLS_TO_NON_PRIMITIVE_FIELD_COUNT"] =
|
|
147
|
+
properties["_CLS_TO_NON_PRIMITIVE_FIELD_COUNT"] = OrderedDict(
|
|
126
148
|
cls_to_non_primitive_field_count
|
|
127
149
|
)
|
|
128
150
|
properties["__slots__"] = tuple(slots)
|
|
@@ -147,7 +169,10 @@ class Serializable(metaclass=SerializableMeta):
|
|
|
147
169
|
_cache_primitive_serial = False
|
|
148
170
|
_ignore_non_existing_keys = False
|
|
149
171
|
|
|
172
|
+
_LEGACY_NAME_HASH: int
|
|
150
173
|
_NAME_HASH: int
|
|
174
|
+
_LEGACY_TO_NEW_NAME_HASH: Dict[int, int]
|
|
175
|
+
|
|
151
176
|
_FIELDS: Dict[str, Field]
|
|
152
177
|
_FIELD_ORDER: List[str]
|
|
153
178
|
_FIELD_TO_NAME_HASH: Dict[str, int]
|
|
@@ -233,6 +258,17 @@ class SerializableSerializer(Serializer):
|
|
|
233
258
|
Leverage DictSerializer to perform serde.
|
|
234
259
|
"""
|
|
235
260
|
|
|
261
|
+
@classmethod
|
|
262
|
+
def _log_legacy(cls, context: Dict, key: Any, msg: str, *args, **kwargs):
|
|
263
|
+
level = kwargs.pop("level", logging.WARNING)
|
|
264
|
+
try:
|
|
265
|
+
logged_keys = context[_deprecate_log_key]
|
|
266
|
+
except KeyError:
|
|
267
|
+
logged_keys = context[_deprecate_log_key] = set()
|
|
268
|
+
if key not in logged_keys:
|
|
269
|
+
logged_keys.add(key)
|
|
270
|
+
logger.log(level, msg, *args, **kwargs)
|
|
271
|
+
|
|
236
272
|
@classmethod
|
|
237
273
|
def _get_obj_field_count_key(cls, obj: Serializable, legacy: bool = False):
|
|
238
274
|
return f"FC_{obj._NAME_HASH if not legacy else obj._LEGACY_NAME_HASH}"
|
|
@@ -296,91 +332,79 @@ class SerializableSerializer(Serializer):
|
|
|
296
332
|
else:
|
|
297
333
|
field.set(obj, value)
|
|
298
334
|
|
|
335
|
+
@classmethod
|
|
336
|
+
def _prune_server_fields(
|
|
337
|
+
cls,
|
|
338
|
+
client_cls_to_field_count: Optional[Dict[int, int]],
|
|
339
|
+
server_cls_to_field_count: Dict[int, int],
|
|
340
|
+
server_fields: list,
|
|
341
|
+
legacy_to_new_hash: Dict[int, int],
|
|
342
|
+
) -> list:
|
|
343
|
+
if set(client_cls_to_field_count.keys()) == set(
|
|
344
|
+
server_cls_to_field_count.keys()
|
|
345
|
+
):
|
|
346
|
+
return server_fields
|
|
347
|
+
|
|
348
|
+
new_to_legacy_hash = {v: k for k, v in legacy_to_new_hash.items()}
|
|
349
|
+
ret_server_fields = []
|
|
350
|
+
server_pos = 0
|
|
351
|
+
for cls_hash, count in server_cls_to_field_count.items():
|
|
352
|
+
if (
|
|
353
|
+
cls_hash in client_cls_to_field_count
|
|
354
|
+
or new_to_legacy_hash.get(cls_hash) in client_cls_to_field_count
|
|
355
|
+
):
|
|
356
|
+
ret_server_fields.extend(server_fields[server_pos : server_pos + count])
|
|
357
|
+
server_pos += count
|
|
358
|
+
return ret_server_fields
|
|
359
|
+
|
|
299
360
|
@classmethod
|
|
300
361
|
def _set_field_values(
|
|
301
362
|
cls,
|
|
302
363
|
obj: Serializable,
|
|
303
364
|
values: List[Any],
|
|
304
|
-
client_cls_to_field_count: Optional[Dict[
|
|
365
|
+
client_cls_to_field_count: Optional[Dict[int, int]],
|
|
305
366
|
is_primitive: bool = True,
|
|
306
367
|
):
|
|
307
368
|
obj_class = type(obj)
|
|
369
|
+
legacy_to_new_hash = obj_class._LEGACY_TO_NEW_NAME_HASH
|
|
370
|
+
|
|
308
371
|
if is_primitive:
|
|
309
372
|
server_cls_to_field_count = obj_class._CLS_TO_PRIMITIVE_FIELD_COUNT
|
|
310
|
-
|
|
373
|
+
field_def_list = obj_class._PRIMITIVE_FIELDS
|
|
311
374
|
else:
|
|
312
375
|
server_cls_to_field_count = obj_class._CLS_TO_NON_PRIMITIVE_FIELD_COUNT
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
legacy_to_new_hash = {
|
|
316
|
-
c._LEGACY_NAME_HASH: c._NAME_HASH
|
|
317
|
-
for c in obj_class.__mro__
|
|
318
|
-
if hasattr(c, "_NAME_HASH") and c._LEGACY_NAME_HASH != c._NAME_HASH
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
if client_cls_to_field_count:
|
|
322
|
-
field_num, server_field_num = 0, 0
|
|
323
|
-
for cls_hash, count in client_cls_to_field_count.items():
|
|
324
|
-
# cut values and fields given field distribution
|
|
325
|
-
# at client and server end
|
|
326
|
-
cls_fields = server_fields[server_field_num : field_num + count]
|
|
327
|
-
cls_values = values[field_num : field_num + count]
|
|
328
|
-
for field, value in zip(cls_fields, cls_values):
|
|
329
|
-
if is_primitive:
|
|
330
|
-
value = _restore_primitive_placeholder(value)
|
|
331
|
-
if not is_primitive or value is not _no_field_value:
|
|
332
|
-
cls._set_field_value(obj, field, value)
|
|
333
|
-
field_num += count
|
|
334
|
-
try:
|
|
335
|
-
server_field_num += server_cls_to_field_count[cls_hash]
|
|
336
|
-
except KeyError:
|
|
337
|
-
try:
|
|
338
|
-
# todo remove this fallback when all
|
|
339
|
-
# versions below v1.0.0rc1 is eliminated
|
|
340
|
-
server_field_num += server_cls_to_field_count[
|
|
341
|
-
legacy_to_new_hash[cls_hash]
|
|
342
|
-
]
|
|
343
|
-
except KeyError:
|
|
344
|
-
# it is possible that certain type of field does not exist
|
|
345
|
-
# at server side
|
|
346
|
-
pass
|
|
347
|
-
else:
|
|
348
|
-
# handle legacy serialization style, with all fields sorted by name
|
|
349
|
-
# todo remove this branch when all versions below v0.1.0b5 is eliminated
|
|
350
|
-
from .field import AnyField
|
|
376
|
+
field_def_list = obj_class._NON_PRIMITIVE_FIELDS
|
|
351
377
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if hasattr(obj_class, deprecated_field_attr):
|
|
367
|
-
deprecated_names = set(getattr(obj_class, deprecated_field_attr))
|
|
368
|
-
for field_name in deprecated_names:
|
|
369
|
-
field = AnyField(tag=field_name)
|
|
370
|
-
field.name = field_name
|
|
371
|
-
deprecated_fields.append(field)
|
|
372
|
-
server_fields = sorted(
|
|
373
|
-
server_fields + deprecated_fields, key=lambda f: f.name
|
|
374
|
-
)
|
|
375
|
-
for field, value in zip(server_fields, values):
|
|
378
|
+
server_fields = cls._prune_server_fields(
|
|
379
|
+
client_cls_to_field_count,
|
|
380
|
+
server_cls_to_field_count,
|
|
381
|
+
field_def_list,
|
|
382
|
+
legacy_to_new_hash,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
field_num, server_field_num = 0, 0
|
|
386
|
+
for cls_hash, count in client_cls_to_field_count.items():
|
|
387
|
+
# cut values and fields given field distribution
|
|
388
|
+
# at client and server end
|
|
389
|
+
cls_fields = server_fields[server_field_num : field_num + count]
|
|
390
|
+
cls_values = values[field_num : field_num + count]
|
|
391
|
+
for field, value in zip(cls_fields, cls_values):
|
|
376
392
|
if is_primitive:
|
|
377
393
|
value = _restore_primitive_placeholder(value)
|
|
378
394
|
if not is_primitive or value is not _no_field_value:
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
395
|
+
cls._set_field_value(obj, field, value)
|
|
396
|
+
field_num += count
|
|
397
|
+
try:
|
|
398
|
+
server_field_num += server_cls_to_field_count[cls_hash]
|
|
399
|
+
except KeyError:
|
|
400
|
+
try:
|
|
401
|
+
server_field_num += server_cls_to_field_count[
|
|
402
|
+
legacy_to_new_hash[cls_hash]
|
|
403
|
+
]
|
|
404
|
+
except KeyError:
|
|
405
|
+
# it is possible that certain type of field does not exist
|
|
406
|
+
# at server side
|
|
407
|
+
pass
|
|
384
408
|
|
|
385
409
|
def deserial(self, serialized: List, context: Dict, subs: List) -> Serializable:
|
|
386
410
|
obj_class_name, primitives = serialized
|
|
@@ -395,17 +419,34 @@ class SerializableSerializer(Serializer):
|
|
|
395
419
|
context, self._get_obj_field_count_key(obj)
|
|
396
420
|
)
|
|
397
421
|
if field_count_data is None:
|
|
398
|
-
#
|
|
399
|
-
# versions below v1.0.0rc1 is eliminated
|
|
422
|
+
# try using legacy field count key to get counts
|
|
400
423
|
field_count_data = self.get_public_data(
|
|
401
424
|
context, self._get_obj_field_count_key(obj, legacy=True)
|
|
402
425
|
)
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
426
|
+
|
|
427
|
+
if field_count_data is None:
|
|
428
|
+
self._log_legacy(
|
|
429
|
+
context,
|
|
430
|
+
("MISSING_CLASS", obj_class_name),
|
|
431
|
+
"Field count info of %s not found in serialized data",
|
|
432
|
+
obj_class_name,
|
|
433
|
+
level=logging.ERROR,
|
|
434
|
+
)
|
|
435
|
+
raise MaxFrameDeprecationError(
|
|
436
|
+
"Failed to deserialize request. Please upgrade your "
|
|
437
|
+
"MaxFrame client to the latest release."
|
|
438
|
+
)
|
|
439
|
+
else:
|
|
440
|
+
self._log_legacy(
|
|
441
|
+
context,
|
|
442
|
+
("LEGACY_CLASS", obj_class_name),
|
|
443
|
+
"Class %s used in legacy client",
|
|
444
|
+
obj_class_name,
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
cls_to_prim_key, cls_to_non_prim_key = msgpack.loads(field_count_data)
|
|
448
|
+
cls_to_prim_key = dict(cls_to_prim_key)
|
|
449
|
+
cls_to_non_prim_key = dict(cls_to_non_prim_key)
|
|
409
450
|
|
|
410
451
|
if primitives:
|
|
411
452
|
self._set_field_values(obj, primitives, cls_to_prim_key, True)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 1999-
|
|
1
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -221,7 +221,10 @@ def test_compatible_serializable(set_is_ci):
|
|
|
221
221
|
_ref_val = ReferenceField("ref_val", "MySimpleSerializable")
|
|
222
222
|
_dict_val = DictField("dict_val")
|
|
223
223
|
|
|
224
|
-
class
|
|
224
|
+
class MyMidSerializable(MySimpleSerializable):
|
|
225
|
+
_i_bool_val = Int64Field("i_bool_val", default=True)
|
|
226
|
+
|
|
227
|
+
class MySubSerializable(MyMidSerializable):
|
|
225
228
|
_m_int_val = Int64Field("m_int_val", default=250)
|
|
226
229
|
_m_str_val = StringField("m_str_val", default="SUB_STR")
|
|
227
230
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 1999-
|
|
1
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -39,6 +39,7 @@ try:
|
|
|
39
39
|
except ImportError:
|
|
40
40
|
zoneinfo = None
|
|
41
41
|
|
|
42
|
+
from ...lib.dtypes_extension._fake_arrow_dtype import FakeArrowDtype
|
|
42
43
|
from ...lib.sparse import SparseMatrix
|
|
43
44
|
from ...lib.wrapped_pickle import switch_unpickle
|
|
44
45
|
from ...tests.utils import require_cudf, require_cupy
|
|
@@ -50,11 +51,13 @@ from .. import (
|
|
|
50
51
|
serialize,
|
|
51
52
|
serialize_with_spawn,
|
|
52
53
|
)
|
|
53
|
-
from ..core import ListSerializer, Placeholder
|
|
54
|
+
from ..core import DtypeSerializer, ListSerializer, Placeholder
|
|
54
55
|
|
|
55
56
|
cupy = lazy_import("cupy")
|
|
56
57
|
cudf = lazy_import("cudf")
|
|
57
58
|
|
|
59
|
+
_arrow_dtype_supported = pa is not None and hasattr(pd, "ArrowDtype")
|
|
60
|
+
|
|
58
61
|
|
|
59
62
|
class CustomList(list):
|
|
60
63
|
pass
|
|
@@ -188,7 +191,7 @@ def test_pandas():
|
|
|
188
191
|
"cat_col": pd.Categorical(np.random.choice(list("abcd"), size=(1000,))),
|
|
189
192
|
}
|
|
190
193
|
)
|
|
191
|
-
if
|
|
194
|
+
if _arrow_dtype_supported:
|
|
192
195
|
val["arrow_col"] = pd.Series(
|
|
193
196
|
np.random.rand(1000), dtype=pd.ArrowDtype(pa.float64())
|
|
194
197
|
)
|
|
@@ -203,6 +206,21 @@ def test_pandas():
|
|
|
203
206
|
pd.testing.assert_index_equal(val, deserialize(*serialize(val)))
|
|
204
207
|
|
|
205
208
|
|
|
209
|
+
@switch_unpickle
|
|
210
|
+
@pytest.mark.skipif(_arrow_dtype_supported, reason="pandas doesn't support ArrowDtype")
|
|
211
|
+
def test_fake_arrow_dtype_serde():
|
|
212
|
+
serializer = DtypeSerializer()
|
|
213
|
+
payload, data, ok = serializer.serial(
|
|
214
|
+
FakeArrowDtype(pa.map_(pa.int64(), pa.string())), dict()
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
assert ok
|
|
218
|
+
assert data == []
|
|
219
|
+
assert payload == ["PA", "map<int64, string>"]
|
|
220
|
+
new_dtype = serializer.deserial(payload, dict(), list())
|
|
221
|
+
assert type(new_dtype) == FakeArrowDtype
|
|
222
|
+
|
|
223
|
+
|
|
206
224
|
@pytest.mark.skipif(pa is None, reason="need pyarrow to run the cases")
|
|
207
225
|
@switch_unpickle
|
|
208
226
|
def test_arrow():
|
maxframe/session.py
CHANGED
maxframe/tensor/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Copyright 1999-
|
|
3
|
+
# Copyright 1999-2025 Alibaba Group Holding Ltd.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|