From d0e7cdbf571d45c39815108a84b89357b1771ca7 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 11:44:29 +0800 Subject: [PATCH 1/6] Speedup mars serialization by adding cache and skip __init__ in deserialization --- ci/remove_tracer_errors.py | 13 +- docs/source/conf.py | 76 +++--- mars/core/entity/tileables.py | 3 + mars/dataframe/core.py | 20 +- mars/dataframe/datasource/dataframe.py | 2 +- mars/serialization/serializables/core.py | 9 +- mars/serialization/serializables/field.py | 8 + mars/services/subtask/core.py | 4 + mars/tensor/core.py | 1 + versioneer.py | 301 +++++++++++++--------- 10 files changed, 264 insertions(+), 173 deletions(-) diff --git a/ci/remove_tracer_errors.py b/ci/remove_tracer_errors.py index ea6f6f1a33..b4c383e6c9 100755 --- a/ci/remove_tracer_errors.py +++ b/ci/remove_tracer_errors.py @@ -29,19 +29,20 @@ def check_coverage_file(file_name): try: conn = sqlite3.connect(file_name) - tracers = list(conn.execute('SELECT * FROM tracer')) + tracers = list(conn.execute("SELECT * FROM tracer")) if len(tracers) < 1: - raise ValueError('File containing no tracers') + raise ValueError("File containing no tracers") except Exception as exc: # noqa: E722 - logger.warning('Failed to resolve coverage file %s due to error %r', - file_name, exc) + logger.warning( + "Failed to resolve coverage file %s due to error %r", file_name, exc + ) os.unlink(file_name) def main(): - for cov_file in glob.glob('.coverage.*'): + for cov_file in glob.glob(".coverage.*"): check_coverage_file(cov_file) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/docs/source/conf.py b/docs/source/conf.py index fa7b779e3a..08192969bd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,9 +20,9 @@ # -- Project information ----------------------------------------------------- from mars import __version__ -project = 'mars' -copyright = '1999-2020, The Alibaba Group Holding Ltd.' -author = 'jisheng, qinxing' +project = "mars" +copyright = "1999-2020, The Alibaba Group Holding Ltd." +author = "jisheng, qinxing" # The short X.Y version version = __version__ @@ -40,29 +40,29 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.mathjax', - 'sphinx.ext.ifconfig', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', - 'sphinx.ext.githubpages', - 'sphinx.ext.autosummary', - 'sphinx.ext.napoleon', - 'IPython.sphinxext.ipython_directive', - 'IPython.sphinxext.ipython_console_highlighting', - 'matplotlib.sphinxext.plot_directive', + "sphinx.ext.mathjax", + "sphinx.ext.ifconfig", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx.ext.githubpages", + "sphinx.ext.autosummary", + "sphinx.ext.napoleon", + "IPython.sphinxext.ipython_directive", + "IPython.sphinxext.ipython_console_highlighting", + "matplotlib.sphinxext.plot_directive", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The master toctree document. -master_doc = 'index' +master_doc = "index" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -77,7 +77,7 @@ exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # -- Options for HTML output ------------------------------------------------- @@ -85,8 +85,8 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'pydata_sphinx_theme' -html_logo = 'images/mars.svg' +html_theme = "pydata_sphinx_theme" +html_logo = "images/mars.svg" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -96,14 +96,17 @@ "github_url": "https://github.com/mars-project/mars", "twitter_url": "https://twitter.com/pymars_dev", "external_links": [ - {"name": "Release Notes", "url": "https://github.com/mars-project/mars/releases"}, - ] + { + "name": "Release Notes", + "url": "https://github.com/mars-project/mars/releases", + }, + ], } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['images'] +html_static_path = ["images"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. @@ -119,7 +122,7 @@ # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. -htmlhelp_basename = 'marsdoc' +htmlhelp_basename = "marsdoc" # -- Options for LaTeX output ------------------------------------------------ @@ -128,15 +131,12 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # 'preamble': '', - # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -146,8 +146,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'mars.tex', 'mars Documentation', - 'jisheng,qinxing', 'manual'), + (master_doc, "mars.tex", "mars Documentation", "jisheng,qinxing", "manual"), ] @@ -155,10 +154,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'mars', 'mars Documentation', - [author], 1) -] +man_pages = [(master_doc, "mars", "mars Documentation", [author], 1)] # -- Options for Texinfo output ---------------------------------------------- @@ -167,9 +163,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'mars', 'mars Documentation', - author, 'mars', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "mars", + "mars Documentation", + author, + "mars", + "One line description of project.", + "Miscellaneous", + ), ] autosummary_generate = True @@ -191,8 +193,8 @@ # -- Extension configuration ------------------------------------------------- -locale_dirs = ['locale/'] # path is example but recommended. -gettext_compact = False # optional. +locale_dirs = ["locale/"] # path is example but recommended. +gettext_compact = False # optional. ipython_warning_is_error = False diff --git a/mars/core/entity/tileables.py b/mars/core/entity/tileables.py index 9c7bbbc8ea..bf9c6e3216 100644 --- a/mars/core/entity/tileables.py +++ b/mars/core/entity/tileables.py @@ -288,7 +288,10 @@ def __init__(self: TileableType, *args, **kwargs): self._chunks = sorted(chunks, key=attrgetter("index")) except AttributeError: # pragma: no cover pass + self.__mars_init__() + def __mars_init__(self): + super(TileableData, self).__mars_init__() self._entities = WeakSet() self._executed_sessions = [] diff --git a/mars/dataframe/core.py b/mars/dataframe/core.py index f85506a129..e594d8bc40 100644 --- a/mars/dataframe/core.py +++ b/mars/dataframe/core.py @@ -400,7 +400,7 @@ class DtypesValue(Serializable): __slots__ = () _key = StringField("key") - _value = SeriesField("value") + _value = SeriesField("value", cache_serialize=True) def __init__(self, key=None, value=None, **kw): super().__init__(_key=key, _value=value, **kw) @@ -1814,7 +1814,7 @@ def median( class BaseDataFrameChunkData(LazyMetaChunkData): __slots__ = ("_dtypes_value",) - _no_copy_attrs_ = ChunkData._no_copy_attrs_ | {"_dtypes"} + _no_copy_attrs_ = ChunkData._no_copy_attrs_ | {"_dtypes", "_columns_value"} # required fields _shape = TupleField( @@ -1824,7 +1824,7 @@ class BaseDataFrameChunkData(LazyMetaChunkData): on_deserialize=on_deserialize_shape, ) # optional fields - _dtypes = ChunkDtypesField("dtypes") + _dtypes = ChunkDtypesField("dtypes", cache_serialize=True) _index_value = ChunkIndexValueField( "index_value", IndexValue, on_deserialize=_on_deserialize_index_value ) @@ -1849,6 +1849,10 @@ def __init__( _columns_value=columns_value, **kw, ) + self.__mars_init__() + + def __mars_init__(self): + super(BaseDataFrameChunkData, self).__mars_init__() self._dtypes_value = None def __len__(self): @@ -1953,7 +1957,7 @@ class BaseDataFrameData(HasShapeTileableData, _ToPandasMixin): __slots__ = "_accessors", "_dtypes_value", "_dtypes_dict" # optional fields - _dtypes = SeriesField("dtypes") + _dtypes = SeriesField("dtypes", cache_serialize=True) _index_value = ReferenceField( "index_value", IndexValue, on_deserialize=_on_deserialize_index_value ) @@ -1988,6 +1992,10 @@ def __init__( _chunks=chunks, **kw, ) + self.__mars_init__() + + def __mars_init__(self): + super().__mars_init__() self._accessors = dict() self._dtypes_value = None self._dtypes_dict = None @@ -2546,7 +2554,7 @@ def apply_if_callable(maybe_callable, obj, **kwargs): class DataFrameGroupByChunkData(BaseDataFrameChunkData): type_name = "DataFrameGroupBy" - _key_dtypes = SeriesField("key_dtypes") + _key_dtypes = SeriesField("key_dtypes", cache_serialize=True) _selection = AnyField("selection") @property @@ -2650,7 +2658,7 @@ def __len__(self): class DataFrameGroupByData(BaseDataFrameData): type_name = "DataFrameGroupBy" - _key_dtypes = SeriesField("key_dtypes") + _key_dtypes = SeriesField("key_dtypes", cache_serialize=True) _selection = AnyField("selection") _chunks = ListField( "chunks", diff --git a/mars/dataframe/datasource/dataframe.py b/mars/dataframe/datasource/dataframe.py index f581523310..a584df7622 100644 --- a/mars/dataframe/datasource/dataframe.py +++ b/mars/dataframe/datasource/dataframe.py @@ -34,7 +34,7 @@ class DataFrameDataSource(DataFrameOperand, DataFrameOperandMixin): _op_type_ = OperandDef.DATAFRAME_DATA_SOURCE data = DataFrameField("data") - dtypes = SeriesField("dtypes") + dtypes = SeriesField("dtypes", cache_serialize=True) def __init__(self, data=None, dtypes=None, gpu=None, **kw): if dtypes is None and data is not None: diff --git a/mars/serialization/serializables/core.py b/mars/serialization/serializables/core.py index 209606b537..a33bfc556d 100644 --- a/mars/serialization/serializables/core.py +++ b/mars/serialization/serializables/core.py @@ -144,6 +144,11 @@ def __init__(self, *args, **kwargs): for k, v in values.items(): fields[k].set(self, v) + def __mars_init__(self): + """Set object attributes which are not defined using field descriptor. + This method will be invoked when deserialization to set up those fields.""" + pass + def __repr__(self): values = ", ".join( [ @@ -224,7 +229,7 @@ def deserial(self, serialized: Tuple, context: Dict, subs: List) -> Serializable if type(primitives) is not list: primitives = cloudpickle.loads(primitives) - obj = obj_class() + obj = obj_class.__new__(obj_class) if primitives: for field, value in zip(obj_class._PRIMITIVE_FIELDS, primitives): @@ -233,7 +238,7 @@ def deserial(self, serialized: Tuple, context: Dict, subs: List) -> Serializable if obj_class._NON_PRIMITIVE_FIELDS: for field, value in zip(obj_class._NON_PRIMITIVE_FIELDS, subs[0]): self._set_field_value(obj, field, value) - + obj.__mars_init__() return obj diff --git a/mars/serialization/serializables/field.py b/mars/serialization/serializables/field.py index 116c27eac2..46a9750f64 100644 --- a/mars/serialization/serializables/field.py +++ b/mars/serialization/serializables/field.py @@ -40,6 +40,7 @@ class Field(ABC): "get", # The __get__ of member_descriptor "set", # The __set__ of member_descriptor "__delete__", # The __delete__ of member_descriptor + "cache_serialize", ) _tag: str @@ -53,6 +54,7 @@ def __init__( default_factory: Optional[Callable] = None, on_serialize: Callable[[Any], Any] = None, on_deserialize: Callable[[Any], Any] = None, + cache_serialize: bool = False, ): if ( default is not no_default and default_factory is not None @@ -64,6 +66,10 @@ def __init__( self._default_factory = default_factory self._on_serialize = on_serialize self._on_deserialize = on_deserialize + self.cache_serialize = cache_serialize + if cache_serialize: + assert on_serialize is None, on_serialize + assert on_deserialize is None, on_deserialize @property def tag(self): @@ -382,6 +388,7 @@ def __init__( default_factory: Optional[Callable] = None, on_serialize: Callable[[Any], Any] = None, on_deserialize: Callable[[Any], Any] = None, + cache_serialize: bool = False, ): super().__init__( tag, @@ -389,6 +396,7 @@ def __init__( default_factory=default_factory, on_serialize=on_serialize, on_deserialize=on_deserialize, + cache_serialize=cache_serialize, ) if field_type is None: field_type = FieldTypes.any diff --git a/mars/services/subtask/core.py b/mars/services/subtask/core.py index b0914554d3..787ff0322c 100644 --- a/mars/services/subtask/core.py +++ b/mars/services/subtask/core.py @@ -127,6 +127,10 @@ def __init__( required_resource=required_resource, stage_n_outputs=stage_n_outputs, ) + self.__mars_init__() + + def __mars_init__(self): + super(Subtask, self).__mars_init__() self._pure_depend_keys = None self._repr = None diff --git a/mars/tensor/core.py b/mars/tensor/core.py index 2ccf4ba542..7344bfe339 100644 --- a/mars/tensor/core.py +++ b/mars/tensor/core.py @@ -58,6 +58,7 @@ class TensorOrder(Enum): class TensorChunkData(ChunkData): __slots__ = () + _no_copy_attrs_ = ChunkData._no_copy_attrs_ | {"dtype"} type_name = "Tensor" # required fields diff --git a/versioneer.py b/versioneer.py index 2156245ad2..3348535533 100644 --- a/versioneer.py +++ b/versioneer.py @@ -1,4 +1,3 @@ - # Version: 0.23 """The Versioneer - like a rocketeer, but for versions. @@ -310,11 +309,13 @@ def get_root(): setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - err = ("Versioneer was unable to run the project root directory. " - "Versioneer requires setup.py to be executed from " - "its immediate directory (like 'python setup.py COMMAND'), " - "or in a way that lets it use sys.argv[0] to find the root " - "(like 'python path/to/setup.py COMMAND').") + err = ( + "Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND')." + ) raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools @@ -327,8 +328,10 @@ def get_root(): me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir: - print("Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(my_path), versioneer_py)) + print( + "Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py) + ) except NameError: pass return root @@ -373,15 +376,16 @@ class NotThisMethod(Exception): def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f): """Store f in HANDLERS[vcs][method].""" HANDLERS.setdefault(vcs, {})[method] = f return f + return decorate -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, - env=None): +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None @@ -397,10 +401,14 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - process = subprocess.Popen([command] + args, cwd=cwd, env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr - else None), **popen_kwargs) + process = subprocess.Popen( + [command] + args, + cwd=cwd, + env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr else None), + **popen_kwargs, + ) break except OSError: e = sys.exc_info()[1] @@ -423,7 +431,9 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, return stdout, process.returncode -LONG_VERSION_PY['git'] = r''' +LONG_VERSION_PY[ + "git" +] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build @@ -1138,7 +1148,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -1147,7 +1157,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = {r for r in refs if re.search(r'\d', r)} + tags = {r for r in refs if re.search(r"\d", r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -1155,24 +1165,31 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix):] + r = ref[len(tag_prefix) :] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') - if not re.match(r'\d', r): + if not re.match(r"\d", r): continue if verbose: print("picking %s" % r) - return {"version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": None, - "date": date} + return { + "version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": None, + "date": date, + } # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") - return {"version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, "error": "no suitable tags", "date": None} + return { + "version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": "no suitable tags", + "date": None, + } @register_vcs_handler("git", "pieces_from_vcs") @@ -1194,8 +1211,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): env.pop("GIT_DIR", None) runner = functools.partial(runner, env=env) - _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, - hide_stderr=True) + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -1203,10 +1219,19 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = runner(GITS, [ - "describe", "--tags", "--dirty", "--always", "--long", - "--match", f"{tag_prefix}[[:digit:]]*" - ], cwd=root) + describe_out, rc = runner( + GITS, + [ + "describe", + "--tags", + "--dirty", + "--always", + "--long", + "--match", + f"{tag_prefix}[[:digit:]]*", + ], + cwd=root, + ) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") @@ -1221,8 +1246,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None - branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], - cwd=root) + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") @@ -1262,17 +1286,16 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: - git_describe = git_describe[:git_describe.rindex("-dirty")] + git_describe = git_describe[: git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX - mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? - pieces["error"] = ("unable to parse git-describe output: '%s'" - % describe_out) + pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag @@ -1281,10 +1304,12 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" - % (full_tag, tag_prefix)) + pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( + full_tag, + tag_prefix, + ) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix):] + pieces["closest-tag"] = full_tag[len(tag_prefix) :] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) @@ -1357,15 +1382,21 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): - return {"version": dirname[len(parentdir_prefix):], - "full-revisionid": None, - "dirty": False, "error": None, "date": None} + return { + "version": dirname[len(parentdir_prefix) :], + "full-revisionid": None, + "dirty": False, + "error": None, + "date": None, + } rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: - print("Tried directories %s but none started with prefix %s" % - (str(rootdirs), parentdir_prefix)) + print( + "Tried directories %s but none started with prefix %s" + % (str(rootdirs), parentdir_prefix) + ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -1394,11 +1425,13 @@ def versions_from_file(filename): contents = f.read() except OSError: raise NotThisMethod("unable to read _version.py") - mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", - contents, re.M | re.S) + mo = re.search( + r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) if not mo: - mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", - contents, re.M | re.S) + mo = re.search( + r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) @@ -1407,8 +1440,7 @@ def versions_from_file(filename): def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) - contents = json.dumps(versions, sort_keys=True, - indent=1, separators=(",", ": ")) + contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) @@ -1440,8 +1472,7 @@ def render_pep440(pieces): rendered += ".dirty" else: # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) + rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1470,8 +1501,7 @@ def render_pep440_branch(pieces): rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" - rendered += "+untagged.%d.g%s" % (pieces["distance"], - pieces["short"]) + rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1632,11 +1662,13 @@ def render_git_describe_long(pieces): def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: - return {"version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None} + return { + "version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None, + } if not style or style == "default": style = "pep440" # the default @@ -1660,9 +1692,13 @@ def render(pieces, style): else: raise ValueError("unknown style '%s'" % style) - return {"version": rendered, "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], "error": None, - "date": pieces.get("date")} + return { + "version": rendered, + "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], + "error": None, + "date": pieces.get("date"), + } class VersioneerBadRootError(Exception): @@ -1685,8 +1721,9 @@ def get_versions(verbose=False): handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose - assert cfg.versionfile_source is not None, \ - "please set versioneer.versionfile_source" + assert ( + cfg.versionfile_source is not None + ), "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) @@ -1740,9 +1777,13 @@ def get_versions(verbose=False): if verbose: print("unable to compute version") - return {"version": "0+unknown", "full-revisionid": None, - "dirty": None, "error": "unable to compute version", - "date": None} + return { + "version": "0+unknown", + "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", + "date": None, + } def get_version(): @@ -1795,6 +1836,7 @@ def run(self): print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) + cmds["version"] = cmd_version # we override "build_py" in setuptools @@ -1816,8 +1858,8 @@ def run(self): # but the build_py command is not expected to copy any files. # we override different "build_py" commands for both environments - if 'build_py' in cmds: - _build_py = cmds['build_py'] + if "build_py" in cmds: + _build_py = cmds["build_py"] else: from setuptools.command.build_py import build_py as _build_py @@ -1834,14 +1876,14 @@ def run(self): # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: - target_versionfile = os.path.join(self.build_lib, - cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) + cmds["build_py"] = cmd_build_py - if 'build_ext' in cmds: - _build_ext = cmds['build_ext'] + if "build_ext" in cmds: + _build_ext = cmds["build_ext"] else: from setuptools.command.build_ext import build_ext as _build_ext @@ -1859,19 +1901,22 @@ def run(self): return # now locate _version.py in the new build/ directory and replace # it with an updated value - target_versionfile = os.path.join(self.build_lib, - cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) if not os.path.exists(target_versionfile): - print(f"Warning: {target_versionfile} does not exist, skipping " - "version update. This can happen if you are running build_ext " - "without first running build_py.") + print( + f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py." + ) return print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) + cmds["build_ext"] = cmd_build_ext if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe + # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ @@ -1892,17 +1937,21 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % - {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + cmds["build_exe"] = cmd_build_exe del cmds["build_py"] - if 'py2exe' in sys.modules: # py2exe enabled? + if "py2exe" in sys.modules: # py2exe enabled? from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): @@ -1918,18 +1967,22 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % - {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + cmds["py2exe"] = cmd_py2exe # sdist farms its file list building out to egg_info - if 'egg_info' in cmds: - _sdist = cmds['egg_info'] + if "egg_info" in cmds: + _sdist = cmds["egg_info"] else: from setuptools.command.egg_info import egg_info as _egg_info @@ -1942,7 +1995,7 @@ def find_sources(self): # Modify the filelist and normalize it root = get_root() cfg = get_config_from_root(root) - self.filelist.append('versioneer.py') + self.filelist.append("versioneer.py") if cfg.versionfile_source: # There are rare cases where versionfile_source might not be # included by default, so we must be explicit @@ -1955,18 +2008,21 @@ def find_sources(self): # We will instead replicate their final normalization (to unicode, # and POSIX-style paths) from setuptools import unicode_utils - normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') - for f in self.filelist.files] - manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') - with open(manifest_filename, 'w') as fobj: - fobj.write('\n'.join(normalized)) + normalized = [ + unicode_utils.filesys_decode(f).replace(os.sep, "/") + for f in self.filelist.files + ] + + manifest_filename = os.path.join(self.egg_info, "SOURCES.txt") + with open(manifest_filename, "w") as fobj: + fobj.write("\n".join(normalized)) - cmds['egg_info'] = cmd_egg_info + cmds["egg_info"] = cmd_egg_info # we override different "sdist" commands for both environments - if 'sdist' in cmds: - _sdist = cmds['sdist'] + if "sdist" in cmds: + _sdist = cmds["sdist"] else: from setuptools.command.sdist import sdist as _sdist @@ -1988,8 +2044,10 @@ def make_release_tree(self, base_dir, files): # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) - write_to_version_file(target_versionfile, - self._versioneer_generated_versions) + write_to_version_file( + target_versionfile, self._versioneer_generated_versions + ) + cmds["sdist"] = cmd_sdist return cmds @@ -2049,11 +2107,9 @@ def do_setup(): root = get_root() try: cfg = get_config_from_root(root) - except (OSError, configparser.NoSectionError, - configparser.NoOptionError) as e: + except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: if isinstance(e, (OSError, configparser.NoSectionError)): - print("Adding sample versioneer config to setup.cfg", - file=sys.stderr) + print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) @@ -2062,15 +2118,18 @@ def do_setup(): print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write(LONG % {"DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - }) - - ipy = os.path.join(os.path.dirname(cfg.versionfile_source), - "__init__.py") + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: From f055fb609456ced1eee8bf6cd9ca3928ae943272 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 14:50:17 +0800 Subject: [PATCH 2/6] replace no_default in serialization by _NoFieldValue to avoid conflict with replace operand no_default --- mars/serialization/serializables/core.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mars/serialization/serializables/core.py b/mars/serialization/serializables/core.py index a33bfc556d..8ae184c224 100644 --- a/mars/serialization/serializables/core.py +++ b/mars/serialization/serializables/core.py @@ -17,7 +17,6 @@ import cloudpickle -from ...utils import no_default from ..core import Serializer, Placeholder, buffered from .field import Field from .field_type import ( @@ -174,6 +173,10 @@ def copy(self) -> "Serializable": _primitive_serial_cache = weakref.WeakKeyDictionary() +class _NoFieldValue: + pass + + class SerializableSerializer(Serializer): """ Leverage DictSerializer to perform serde. @@ -189,7 +192,7 @@ def _get_field_values(cls, obj: Serializable, fields): value = field.on_serialize(value) except AttributeError: # Most field values are not None, serialize by list is more efficient than dict. - value = no_default + value = _NoFieldValue values.append(value) return values @@ -208,7 +211,7 @@ def serial(self, obj: Serializable, context: Dict): @staticmethod def _set_field_value(obj: Serializable, field: Field, value): - if value is no_default: + if value is _NoFieldValue: return if type(value) is Placeholder: if field.on_deserialize is not None: From 786d1011749ed7bb28b8548d4700f65cd9237d74 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 14:54:02 +0800 Subject: [PATCH 3/6] revert files --- ci/remove_tracer_errors.py | 13 +- docs/source/conf.py | 76 +++++----- versioneer.py | 301 +++++++++++++++---------------------- 3 files changed, 164 insertions(+), 226 deletions(-) diff --git a/ci/remove_tracer_errors.py b/ci/remove_tracer_errors.py index b4c383e6c9..ea6f6f1a33 100755 --- a/ci/remove_tracer_errors.py +++ b/ci/remove_tracer_errors.py @@ -29,20 +29,19 @@ def check_coverage_file(file_name): try: conn = sqlite3.connect(file_name) - tracers = list(conn.execute("SELECT * FROM tracer")) + tracers = list(conn.execute('SELECT * FROM tracer')) if len(tracers) < 1: - raise ValueError("File containing no tracers") + raise ValueError('File containing no tracers') except Exception as exc: # noqa: E722 - logger.warning( - "Failed to resolve coverage file %s due to error %r", file_name, exc - ) + logger.warning('Failed to resolve coverage file %s due to error %r', + file_name, exc) os.unlink(file_name) def main(): - for cov_file in glob.glob(".coverage.*"): + for cov_file in glob.glob('.coverage.*'): check_coverage_file(cov_file) -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/docs/source/conf.py b/docs/source/conf.py index 08192969bd..fa7b779e3a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,9 +20,9 @@ # -- Project information ----------------------------------------------------- from mars import __version__ -project = "mars" -copyright = "1999-2020, The Alibaba Group Holding Ltd." -author = "jisheng, qinxing" +project = 'mars' +copyright = '1999-2020, The Alibaba Group Holding Ltd.' +author = 'jisheng, qinxing' # The short X.Y version version = __version__ @@ -40,29 +40,29 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - "sphinx.ext.mathjax", - "sphinx.ext.ifconfig", - "sphinx.ext.intersphinx", - "sphinx.ext.viewcode", - "sphinx.ext.githubpages", - "sphinx.ext.autosummary", - "sphinx.ext.napoleon", - "IPython.sphinxext.ipython_directive", - "IPython.sphinxext.ipython_console_highlighting", - "matplotlib.sphinxext.plot_directive", + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.intersphinx', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', + 'sphinx.ext.autosummary', + 'sphinx.ext.napoleon', + 'IPython.sphinxext.ipython_directive', + 'IPython.sphinxext.ipython_console_highlighting', + 'matplotlib.sphinxext.plot_directive', ] # Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] +templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = ".rst" +source_suffix = '.rst' # The master toctree document. -master_doc = "index" +master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -77,7 +77,7 @@ exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" +pygments_style = 'sphinx' # -- Options for HTML output ------------------------------------------------- @@ -85,8 +85,8 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = "pydata_sphinx_theme" -html_logo = "images/mars.svg" +html_theme = 'pydata_sphinx_theme' +html_logo = 'images/mars.svg' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -96,17 +96,14 @@ "github_url": "https://github.com/mars-project/mars", "twitter_url": "https://twitter.com/pymars_dev", "external_links": [ - { - "name": "Release Notes", - "url": "https://github.com/mars-project/mars/releases", - }, - ], + {"name": "Release Notes", "url": "https://github.com/mars-project/mars/releases"}, + ] } # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["images"] +html_static_path = ['images'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. @@ -122,7 +119,7 @@ # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. -htmlhelp_basename = "marsdoc" +htmlhelp_basename = 'marsdoc' # -- Options for LaTeX output ------------------------------------------------ @@ -131,12 +128,15 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. # # 'preamble': '', + # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -146,7 +146,8 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "mars.tex", "mars Documentation", "jisheng,qinxing", "manual"), + (master_doc, 'mars.tex', 'mars Documentation', + 'jisheng,qinxing', 'manual'), ] @@ -154,7 +155,10 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "mars", "mars Documentation", [author], 1)] +man_pages = [ + (master_doc, 'mars', 'mars Documentation', + [author], 1) +] # -- Options for Texinfo output ---------------------------------------------- @@ -163,15 +167,9 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ( - master_doc, - "mars", - "mars Documentation", - author, - "mars", - "One line description of project.", - "Miscellaneous", - ), + (master_doc, 'mars', 'mars Documentation', + author, 'mars', 'One line description of project.', + 'Miscellaneous'), ] autosummary_generate = True @@ -193,8 +191,8 @@ # -- Extension configuration ------------------------------------------------- -locale_dirs = ["locale/"] # path is example but recommended. -gettext_compact = False # optional. +locale_dirs = ['locale/'] # path is example but recommended. +gettext_compact = False # optional. ipython_warning_is_error = False diff --git a/versioneer.py b/versioneer.py index 3348535533..2156245ad2 100644 --- a/versioneer.py +++ b/versioneer.py @@ -1,3 +1,4 @@ + # Version: 0.23 """The Versioneer - like a rocketeer, but for versions. @@ -309,13 +310,11 @@ def get_root(): setup_py = os.path.join(root, "setup.py") versioneer_py = os.path.join(root, "versioneer.py") if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): - err = ( - "Versioneer was unable to run the project root directory. " - "Versioneer requires setup.py to be executed from " - "its immediate directory (like 'python setup.py COMMAND'), " - "or in a way that lets it use sys.argv[0] to find the root " - "(like 'python path/to/setup.py COMMAND')." - ) + err = ("Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND').") raise VersioneerBadRootError(err) try: # Certain runtime workflows (setup.py install/develop in a setuptools @@ -328,10 +327,8 @@ def get_root(): me_dir = os.path.normcase(os.path.splitext(my_path)[0]) vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) if me_dir != vsr_dir: - print( - "Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(my_path), versioneer_py) - ) + print("Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(my_path), versioneer_py)) except NameError: pass return root @@ -376,16 +373,15 @@ class NotThisMethod(Exception): def register_vcs_handler(vcs, method): # decorator """Create decorator to mark a method as the handler of a VCS.""" - def decorate(f): """Store f in HANDLERS[vcs][method].""" HANDLERS.setdefault(vcs, {})[method] = f return f - return decorate -def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): """Call the given command(s).""" assert isinstance(commands, list) process = None @@ -401,14 +397,10 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= try: dispcmd = str([command] + args) # remember shell=False, so use git.cmd on windows, not just git - process = subprocess.Popen( - [command] + args, - cwd=cwd, - env=env, - stdout=subprocess.PIPE, - stderr=(subprocess.PIPE if hide_stderr else None), - **popen_kwargs, - ) + process = subprocess.Popen([command] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None), **popen_kwargs) break except OSError: e = sys.exc_info()[1] @@ -431,9 +423,7 @@ def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env= return stdout, process.returncode -LONG_VERSION_PY[ - "git" -] = r''' +LONG_VERSION_PY['git'] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build @@ -1148,7 +1138,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)} + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -1157,7 +1147,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = {r for r in refs if re.search(r"\d", r)} + tags = {r for r in refs if re.search(r'\d', r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -1165,31 +1155,24 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): for ref in sorted(tags): # sorting will prefer e.g. "2.0" over "2.0rc1" if ref.startswith(tag_prefix): - r = ref[len(tag_prefix) :] + r = ref[len(tag_prefix):] # Filter out refs that exactly match prefix or that don't start # with a number once the prefix is stripped (mostly a concern # when prefix is '') - if not re.match(r"\d", r): + if not re.match(r'\d', r): continue if verbose: print("picking %s" % r) - return { - "version": r, - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": None, - "date": date, - } + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} # no suitable tags, so version is "0+unknown", but full hex is still there if verbose: print("no suitable tags, using unknown + full revision id") - return { - "version": "0+unknown", - "full-revisionid": keywords["full"].strip(), - "dirty": False, - "error": "no suitable tags", - "date": None, - } + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} @register_vcs_handler("git", "pieces_from_vcs") @@ -1211,7 +1194,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): env.pop("GIT_DIR", None) runner = functools.partial(runner, env=env) - _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) + _, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -1219,19 +1203,10 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] # if there isn't one, this yields HEX[-dirty] (no NUM) - describe_out, rc = runner( - GITS, - [ - "describe", - "--tags", - "--dirty", - "--always", - "--long", - "--match", - f"{tag_prefix}[[:digit:]]*", - ], - cwd=root, - ) + describe_out, rc = runner(GITS, [ + "describe", "--tags", "--dirty", "--always", "--long", + "--match", f"{tag_prefix}[[:digit:]]*" + ], cwd=root) # --long was added in git-1.5.5 if describe_out is None: raise NotThisMethod("'git describe' failed") @@ -1246,7 +1221,8 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): pieces["short"] = full_out[:7] # maybe improved later pieces["error"] = None - branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], cwd=root) + branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"], + cwd=root) # --abbrev-ref was added in git-1.6.3 if rc != 0 or branch_name is None: raise NotThisMethod("'git rev-parse --abbrev-ref' returned error") @@ -1286,16 +1262,17 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): dirty = git_describe.endswith("-dirty") pieces["dirty"] = dirty if dirty: - git_describe = git_describe[: git_describe.rindex("-dirty")] + git_describe = git_describe[:git_describe.rindex("-dirty")] # now we have TAG-NUM-gHEX or HEX if "-" in git_describe: # TAG-NUM-gHEX - mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) if not mo: # unparsable. Maybe git-describe is misbehaving? - pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) return pieces # tag @@ -1304,12 +1281,10 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( - full_tag, - tag_prefix, - ) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) return pieces - pieces["closest-tag"] = full_tag[len(tag_prefix) :] + pieces["closest-tag"] = full_tag[len(tag_prefix):] # distance: number of commits since tag pieces["distance"] = int(mo.group(2)) @@ -1382,21 +1357,15 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): for _ in range(3): dirname = os.path.basename(root) if dirname.startswith(parentdir_prefix): - return { - "version": dirname[len(parentdir_prefix) :], - "full-revisionid": None, - "dirty": False, - "error": None, - "date": None, - } + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} rootdirs.append(root) root = os.path.dirname(root) # up a level if verbose: - print( - "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) - ) + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -1425,13 +1394,11 @@ def versions_from_file(filename): contents = f.read() except OSError: raise NotThisMethod("unable to read _version.py") - mo = re.search( - r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S - ) + mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) if not mo: - mo = re.search( - r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S - ) + mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON", + contents, re.M | re.S) if not mo: raise NotThisMethod("no version_json in _version.py") return json.loads(mo.group(1)) @@ -1440,7 +1407,8 @@ def versions_from_file(filename): def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) - contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) + contents = json.dumps(versions, sort_keys=True, + indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) @@ -1472,7 +1440,8 @@ def render_pep440(pieces): rendered += ".dirty" else: # exception #1 - rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1501,7 +1470,8 @@ def render_pep440_branch(pieces): rendered = "0" if pieces["branch"] != "master": rendered += ".dev0" - rendered += "+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) + rendered += "+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) if pieces["dirty"]: rendered += ".dirty" return rendered @@ -1662,13 +1632,11 @@ def render_git_describe_long(pieces): def render(pieces, style): """Render the given version pieces into the requested style.""" if pieces["error"]: - return { - "version": "unknown", - "full-revisionid": pieces.get("long"), - "dirty": None, - "error": pieces["error"], - "date": None, - } + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} if not style or style == "default": style = "pep440" # the default @@ -1692,13 +1660,9 @@ def render(pieces, style): else: raise ValueError("unknown style '%s'" % style) - return { - "version": rendered, - "full-revisionid": pieces["long"], - "dirty": pieces["dirty"], - "error": None, - "date": pieces.get("date"), - } + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} class VersioneerBadRootError(Exception): @@ -1721,9 +1685,8 @@ def get_versions(verbose=False): handlers = HANDLERS.get(cfg.VCS) assert handlers, "unrecognized VCS '%s'" % cfg.VCS verbose = verbose or cfg.verbose - assert ( - cfg.versionfile_source is not None - ), "please set versioneer.versionfile_source" + assert cfg.versionfile_source is not None, \ + "please set versioneer.versionfile_source" assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" versionfile_abs = os.path.join(root, cfg.versionfile_source) @@ -1777,13 +1740,9 @@ def get_versions(verbose=False): if verbose: print("unable to compute version") - return { - "version": "0+unknown", - "full-revisionid": None, - "dirty": None, - "error": "unable to compute version", - "date": None, - } + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, "error": "unable to compute version", + "date": None} def get_version(): @@ -1836,7 +1795,6 @@ def run(self): print(" date: %s" % vers.get("date")) if vers["error"]: print(" error: %s" % vers["error"]) - cmds["version"] = cmd_version # we override "build_py" in setuptools @@ -1858,8 +1816,8 @@ def run(self): # but the build_py command is not expected to copy any files. # we override different "build_py" commands for both environments - if "build_py" in cmds: - _build_py = cmds["build_py"] + if 'build_py' in cmds: + _build_py = cmds['build_py'] else: from setuptools.command.build_py import build_py as _build_py @@ -1876,14 +1834,14 @@ def run(self): # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: - target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) - cmds["build_py"] = cmd_build_py - if "build_ext" in cmds: - _build_ext = cmds["build_ext"] + if 'build_ext' in cmds: + _build_ext = cmds['build_ext'] else: from setuptools.command.build_ext import build_ext as _build_ext @@ -1901,22 +1859,19 @@ def run(self): return # now locate _version.py in the new build/ directory and replace # it with an updated value - target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) + target_versionfile = os.path.join(self.build_lib, + cfg.versionfile_build) if not os.path.exists(target_versionfile): - print( - f"Warning: {target_versionfile} does not exist, skipping " - "version update. This can happen if you are running build_ext " - "without first running build_py." - ) + print(f"Warning: {target_versionfile} does not exist, skipping " + "version update. This can happen if you are running build_ext " + "without first running build_py.") return print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) - cmds["build_ext"] = cmd_build_ext if "cx_Freeze" in sys.modules: # cx_freeze enabled? from cx_Freeze.dist import build_exe as _build_exe - # nczeczulin reports that py2exe won't like the pep440-style string # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. # setup(console=[{ @@ -1937,21 +1892,17 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) cmds["build_exe"] = cmd_build_exe del cmds["build_py"] - if "py2exe" in sys.modules: # py2exe enabled? + if 'py2exe' in sys.modules: # py2exe enabled? from py2exe.distutils_buildexe import py2exe as _py2exe class cmd_py2exe(_py2exe): @@ -1967,22 +1918,18 @@ def run(self): os.unlink(target_versionfile) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - + f.write(LONG % + {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) cmds["py2exe"] = cmd_py2exe # sdist farms its file list building out to egg_info - if "egg_info" in cmds: - _sdist = cmds["egg_info"] + if 'egg_info' in cmds: + _sdist = cmds['egg_info'] else: from setuptools.command.egg_info import egg_info as _egg_info @@ -1995,7 +1942,7 @@ def find_sources(self): # Modify the filelist and normalize it root = get_root() cfg = get_config_from_root(root) - self.filelist.append("versioneer.py") + self.filelist.append('versioneer.py') if cfg.versionfile_source: # There are rare cases where versionfile_source might not be # included by default, so we must be explicit @@ -2008,21 +1955,18 @@ def find_sources(self): # We will instead replicate their final normalization (to unicode, # and POSIX-style paths) from setuptools import unicode_utils + normalized = [unicode_utils.filesys_decode(f).replace(os.sep, '/') + for f in self.filelist.files] - normalized = [ - unicode_utils.filesys_decode(f).replace(os.sep, "/") - for f in self.filelist.files - ] - - manifest_filename = os.path.join(self.egg_info, "SOURCES.txt") - with open(manifest_filename, "w") as fobj: - fobj.write("\n".join(normalized)) + manifest_filename = os.path.join(self.egg_info, 'SOURCES.txt') + with open(manifest_filename, 'w') as fobj: + fobj.write('\n'.join(normalized)) - cmds["egg_info"] = cmd_egg_info + cmds['egg_info'] = cmd_egg_info # we override different "sdist" commands for both environments - if "sdist" in cmds: - _sdist = cmds["sdist"] + if 'sdist' in cmds: + _sdist = cmds['sdist'] else: from setuptools.command.sdist import sdist as _sdist @@ -2044,10 +1988,8 @@ def make_release_tree(self, base_dir, files): # updated value target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) - write_to_version_file( - target_versionfile, self._versioneer_generated_versions - ) - + write_to_version_file(target_versionfile, + self._versioneer_generated_versions) cmds["sdist"] = cmd_sdist return cmds @@ -2107,9 +2049,11 @@ def do_setup(): root = get_root() try: cfg = get_config_from_root(root) - except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: + except (OSError, configparser.NoSectionError, + configparser.NoOptionError) as e: if isinstance(e, (OSError, configparser.NoSectionError)): - print("Adding sample versioneer config to setup.cfg", file=sys.stderr) + print("Adding sample versioneer config to setup.cfg", + file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) @@ -2118,18 +2062,15 @@ def do_setup(): print(" creating %s" % cfg.versionfile_source) with open(cfg.versionfile_source, "w") as f: LONG = LONG_VERSION_PY[cfg.VCS] - f.write( - LONG - % { - "DOLLAR": "$", - "STYLE": cfg.style, - "TAG_PREFIX": cfg.tag_prefix, - "PARENTDIR_PREFIX": cfg.parentdir_prefix, - "VERSIONFILE_SOURCE": cfg.versionfile_source, - } - ) - - ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") + f.write(LONG % {"DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + }) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), + "__init__.py") if os.path.exists(ipy): try: with open(ipy, "r") as f: From c3354b1b183f10e1468ebed91d2211c6d9761281 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 15:25:33 +0800 Subject: [PATCH 4/6] refactor __mars_init__ to __on_deserialize__ --- mars/core/entity/tileables.py | 7 ++++--- mars/dataframe/core.py | 14 ++++++++------ mars/serialization/serializables/core.py | 6 +++--- mars/services/subtask/core.py | 7 ++++--- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/mars/core/entity/tileables.py b/mars/core/entity/tileables.py index bf9c6e3216..8d1dda5ea5 100644 --- a/mars/core/entity/tileables.py +++ b/mars/core/entity/tileables.py @@ -288,10 +288,11 @@ def __init__(self: TileableType, *args, **kwargs): self._chunks = sorted(chunks, key=attrgetter("index")) except AttributeError: # pragma: no cover pass - self.__mars_init__() + self._entities = WeakSet() + self._executed_sessions = [] - def __mars_init__(self): - super(TileableData, self).__mars_init__() + def __on_deserialize__(self): + super(TileableData, self).__on_deserialize__() self._entities = WeakSet() self._executed_sessions = [] diff --git a/mars/dataframe/core.py b/mars/dataframe/core.py index e594d8bc40..a77a2487e0 100644 --- a/mars/dataframe/core.py +++ b/mars/dataframe/core.py @@ -1849,10 +1849,10 @@ def __init__( _columns_value=columns_value, **kw, ) - self.__mars_init__() + self._dtypes_value = None - def __mars_init__(self): - super(BaseDataFrameChunkData, self).__mars_init__() + def __on_deserialize__(self): + super(BaseDataFrameChunkData, self).__on_deserialize__() self._dtypes_value = None def __len__(self): @@ -1992,10 +1992,12 @@ def __init__( _chunks=chunks, **kw, ) - self.__mars_init__() + self._accessors = dict() + self._dtypes_value = None + self._dtypes_dict = None - def __mars_init__(self): - super().__mars_init__() + def __on_deserialize__(self): + super().__on_deserialize__() self._accessors = dict() self._dtypes_value = None self._dtypes_dict = None diff --git a/mars/serialization/serializables/core.py b/mars/serialization/serializables/core.py index 8ae184c224..bc96ec2824 100644 --- a/mars/serialization/serializables/core.py +++ b/mars/serialization/serializables/core.py @@ -143,9 +143,9 @@ def __init__(self, *args, **kwargs): for k, v in values.items(): fields[k].set(self, v) - def __mars_init__(self): + def __on_deserialize__(self): """Set object attributes which are not defined using field descriptor. - This method will be invoked when deserialization to set up those fields.""" + This method will be invoked when deserialization to set defaults values for those fields.""" pass def __repr__(self): @@ -241,7 +241,7 @@ def deserial(self, serialized: Tuple, context: Dict, subs: List) -> Serializable if obj_class._NON_PRIMITIVE_FIELDS: for field, value in zip(obj_class._NON_PRIMITIVE_FIELDS, subs[0]): self._set_field_value(obj, field, value) - obj.__mars_init__() + obj.__on_deserialize__() return obj diff --git a/mars/services/subtask/core.py b/mars/services/subtask/core.py index 787ff0322c..29d02d6e56 100644 --- a/mars/services/subtask/core.py +++ b/mars/services/subtask/core.py @@ -127,10 +127,11 @@ def __init__( required_resource=required_resource, stage_n_outputs=stage_n_outputs, ) - self.__mars_init__() + self._pure_depend_keys = None + self._repr = None - def __mars_init__(self): - super(Subtask, self).__mars_init__() + def __on_deserialize__(self): + super(Subtask, self).__on_deserialize__() self._pure_depend_keys = None self._repr = None From 388b31470e384b04183c279059ada26f4092840d Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 15:31:35 +0800 Subject: [PATCH 5/6] remove unnecessary docs --- mars/serialization/serializables/core.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/mars/serialization/serializables/core.py b/mars/serialization/serializables/core.py index bc96ec2824..a943784456 100644 --- a/mars/serialization/serializables/core.py +++ b/mars/serialization/serializables/core.py @@ -144,8 +144,6 @@ def __init__(self, *args, **kwargs): fields[k].set(self, v) def __on_deserialize__(self): - """Set object attributes which are not defined using field descriptor. - This method will be invoked when deserialization to set defaults values for those fields.""" pass def __repr__(self): From 735e7d5582ba8c6226e3b6818bd44a9be254ddb2 Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Thu, 20 Oct 2022 15:42:09 +0800 Subject: [PATCH 6/6] revert cache_serialize --- mars/dataframe/core.py | 10 +++++----- mars/dataframe/datasource/dataframe.py | 2 +- mars/serialization/serializables/field.py | 8 -------- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/mars/dataframe/core.py b/mars/dataframe/core.py index a77a2487e0..33289d38ba 100644 --- a/mars/dataframe/core.py +++ b/mars/dataframe/core.py @@ -400,7 +400,7 @@ class DtypesValue(Serializable): __slots__ = () _key = StringField("key") - _value = SeriesField("value", cache_serialize=True) + _value = SeriesField("value") def __init__(self, key=None, value=None, **kw): super().__init__(_key=key, _value=value, **kw) @@ -1824,7 +1824,7 @@ class BaseDataFrameChunkData(LazyMetaChunkData): on_deserialize=on_deserialize_shape, ) # optional fields - _dtypes = ChunkDtypesField("dtypes", cache_serialize=True) + _dtypes = ChunkDtypesField("dtypes") _index_value = ChunkIndexValueField( "index_value", IndexValue, on_deserialize=_on_deserialize_index_value ) @@ -1957,7 +1957,7 @@ class BaseDataFrameData(HasShapeTileableData, _ToPandasMixin): __slots__ = "_accessors", "_dtypes_value", "_dtypes_dict" # optional fields - _dtypes = SeriesField("dtypes", cache_serialize=True) + _dtypes = SeriesField("dtypes") _index_value = ReferenceField( "index_value", IndexValue, on_deserialize=_on_deserialize_index_value ) @@ -2556,7 +2556,7 @@ def apply_if_callable(maybe_callable, obj, **kwargs): class DataFrameGroupByChunkData(BaseDataFrameChunkData): type_name = "DataFrameGroupBy" - _key_dtypes = SeriesField("key_dtypes", cache_serialize=True) + _key_dtypes = SeriesField("key_dtypes") _selection = AnyField("selection") @property @@ -2660,7 +2660,7 @@ def __len__(self): class DataFrameGroupByData(BaseDataFrameData): type_name = "DataFrameGroupBy" - _key_dtypes = SeriesField("key_dtypes", cache_serialize=True) + _key_dtypes = SeriesField("key_dtypes") _selection = AnyField("selection") _chunks = ListField( "chunks", diff --git a/mars/dataframe/datasource/dataframe.py b/mars/dataframe/datasource/dataframe.py index a584df7622..f581523310 100644 --- a/mars/dataframe/datasource/dataframe.py +++ b/mars/dataframe/datasource/dataframe.py @@ -34,7 +34,7 @@ class DataFrameDataSource(DataFrameOperand, DataFrameOperandMixin): _op_type_ = OperandDef.DATAFRAME_DATA_SOURCE data = DataFrameField("data") - dtypes = SeriesField("dtypes", cache_serialize=True) + dtypes = SeriesField("dtypes") def __init__(self, data=None, dtypes=None, gpu=None, **kw): if dtypes is None and data is not None: diff --git a/mars/serialization/serializables/field.py b/mars/serialization/serializables/field.py index 46a9750f64..116c27eac2 100644 --- a/mars/serialization/serializables/field.py +++ b/mars/serialization/serializables/field.py @@ -40,7 +40,6 @@ class Field(ABC): "get", # The __get__ of member_descriptor "set", # The __set__ of member_descriptor "__delete__", # The __delete__ of member_descriptor - "cache_serialize", ) _tag: str @@ -54,7 +53,6 @@ def __init__( default_factory: Optional[Callable] = None, on_serialize: Callable[[Any], Any] = None, on_deserialize: Callable[[Any], Any] = None, - cache_serialize: bool = False, ): if ( default is not no_default and default_factory is not None @@ -66,10 +64,6 @@ def __init__( self._default_factory = default_factory self._on_serialize = on_serialize self._on_deserialize = on_deserialize - self.cache_serialize = cache_serialize - if cache_serialize: - assert on_serialize is None, on_serialize - assert on_deserialize is None, on_deserialize @property def tag(self): @@ -388,7 +382,6 @@ def __init__( default_factory: Optional[Callable] = None, on_serialize: Callable[[Any], Any] = None, on_deserialize: Callable[[Any], Any] = None, - cache_serialize: bool = False, ): super().__init__( tag, @@ -396,7 +389,6 @@ def __init__( default_factory=default_factory, on_serialize=on_serialize, on_deserialize=on_deserialize, - cache_serialize=cache_serialize, ) if field_type is None: field_type = FieldTypes.any