From 7b1680949a4f73d0c996329910d9092c12297ebd Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 13 Jul 2022 14:12:03 -0400 Subject: [PATCH 1/2] Add encoding to file open calls. --- .pylintrc | 3 +-- .pylintrc39 | 3 +-- dash/development/_jl_components_generation.py | 6 +++--- dash/development/_py_components_generation.py | 6 ++++-- dash/development/_r_components_generation.py | 18 +++++++++--------- dash/development/build_process.py | 10 ++++++---- dash/development/component_generator.py | 8 +++++--- dash/development/component_loader.py | 2 +- dash/development/update_components.py | 2 +- dash/testing/application_runners.py | 4 ++-- setup.py | 4 ++-- 11 files changed, 35 insertions(+), 31 deletions(-) diff --git a/.pylintrc b/.pylintrc index 8c70f5caaf..be4cbe086b 100644 --- a/.pylintrc +++ b/.pylintrc @@ -68,8 +68,7 @@ disable=fixme, superfluous-parens, bad-continuation, line-too-long, - bad-option-value, - unspecified-encoding + bad-option-value # Enable the message, report, category or checker with the given id(s). You can diff --git a/.pylintrc39 b/.pylintrc39 index 00dab4da11..05d1d677b9 100644 --- a/.pylintrc39 +++ b/.pylintrc39 @@ -159,8 +159,7 @@ disable=invalid-name, line-too-long, super-with-arguments, raise-missing-from, - bad-option-value, - unspecified-encoding + bad-option-value # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/dash/development/_jl_components_generation.py b/dash/development/_jl_components_generation.py index a21d599f25..9fe33618dc 100644 --- a/dash/development/_jl_components_generation.py +++ b/dash/development/_jl_components_generation.py @@ -404,7 +404,7 @@ def generate_package_file(project_shortname, components, pkg_data, prefix): base_package=base_package_name(project_shortname), ) file_path = os.path.join("src", package_name + ".jl") - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(package_string) print("Generated {}".format(file_path)) @@ -435,7 +435,7 @@ def generate_toml_file(project_shortname, pkg_data): dash_uuid=base_package_uid(project_shortname), ) file_path = "Project.toml" - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(toml_string) print("Generated {}".format(file_path)) @@ -509,7 +509,7 @@ def generate_struct_file(name, props, description, project_shortname, prefix): os.makedirs("src/jl") file_path = os.path.join("src", "jl", file_name) - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(import_string) f.write(class_string) diff --git a/dash/development/_py_components_generation.py b/dash/development/_py_components_generation.py index 6b6907e91e..48b8aac5ae 100644 --- a/dash/development/_py_components_generation.py +++ b/dash/development/_py_components_generation.py @@ -169,7 +169,7 @@ def generate_class_file( file_name = f"{typename:s}.py" file_path = os.path.join(namespace, file_name) - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(import_string) f.write(class_string) @@ -177,7 +177,9 @@ def generate_class_file( def generate_imports(project_shortname, components): - with open(os.path.join(project_shortname, "_imports_.py"), "w") as f: + with open( + os.path.join(project_shortname, "_imports_.py"), "w", encoding="utf-8" + ) as f: component_imports = "\n".join(f"from .{x} import {x}" for x in components) all_list = ",\n".join(f' "{x}"' for x in components) imports_string = f"{component_imports}\n\n__all__ = [\n{all_list}\n]" diff --git a/dash/development/_r_components_generation.py b/dash/development/_r_components_generation.py index 35dde326a9..c2b0bffd4b 100644 --- a/dash/development/_r_components_generation.py +++ b/dash/development/_r_components_generation.py @@ -425,7 +425,7 @@ def write_help_file(name, props, description, prefix, rpkg_data): # textwrap.fill, starting from the beginning of the usage string file_path = os.path.join("man", file_name) - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write( help_string.format( funcname=funcname, @@ -447,7 +447,7 @@ def write_help_file(name, props, description, prefix, rpkg_data): "examples", wrap("dontrun" if the_ex.get("dontrun") else "", the_ex["code"]), ) - with open(file_path, "a+") as fa: + with open(file_path, "a+", encoding="utf-8") as fa: fa.write(result + "\n") @@ -475,7 +475,7 @@ def write_class_file( file_name = format_fn_name(prefix, name) + ".R" file_path = os.path.join("R", file_name) - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(import_string) f.write(class_string) @@ -504,7 +504,7 @@ def write_js_metadata(pkg_data, project_shortname, has_wildcards): os.makedirs("R") file_path = os.path.join("R", file_name) - with open(file_path, "w") as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(function_string) if has_wildcards: f.write(wildcard_helper) @@ -687,12 +687,12 @@ def generate_rpkg( # this avoids having to generate an RData file from within Python. write_js_metadata(pkg_data, project_shortname, has_wildcards) - with open("NAMESPACE", "w+") as f: + with open("NAMESPACE", "w+", encoding="utf-8") as f: f.write(import_string) f.write(export_string) f.write(packages_string) - with open(".Rbuildignore", "w+") as f2: + with open(".Rbuildignore", "w+", encoding="utf-8") as f2: f2.write(rbuild_ignore_string) description_string = description_template.format( @@ -711,7 +711,7 @@ def generate_rpkg( vignette_builder=vignette_builder, ) - with open("DESCRIPTION", "w+") as f3: + with open("DESCRIPTION", "w+", encoding="utf-8") as f3: f3.write(description_string) if rpkg_data is not None: @@ -723,7 +723,7 @@ def generate_rpkg( lib_name=lib_name, maintainer=maintainer, ) - with open(pkghelp_stub_path, "w") as f4: + with open(pkghelp_stub_path, "w", encoding="utf-8") as f4: f4.write(pkghelp) @@ -807,7 +807,7 @@ def make_namespace_exports(components, prefix): rfilelist += [os.path.join("R", script)] for rfile in rfilelist: - with open(rfile, "r") as script: + with open(rfile, "r", encoding="utf-8") as script: s = script.read() # remove comments diff --git a/dash/development/build_process.py b/dash/development/build_process.py index b34c5d1dd8..ff1bcffcf6 100644 --- a/dash/development/build_process.py +++ b/dash/development/build_process.py @@ -29,7 +29,7 @@ def __init__(self, main, deps_info): self.asset_paths = (self.deps_folder, self.npm_modules) def _parse_package(self, path): - with open(path, "r") as fp: + with open(path, "r", encoding="utf-8") as fp: package = json.load(fp) self.version = package["version"] self.name = package["name"] @@ -99,7 +99,7 @@ def digest(self): for copy in copies: payload[f"MD5 ({copy})"] = compute_md5(self._concat(folder, copy)) - with open(self._concat(self.main, "digest.json"), "w") as fp: + with open(self._concat(self.main, "digest.json"), "w", encoding="utf-8") as fp: json.dump(payload, fp, sort_keys=True, indent=4, separators=(",", ":")) logger.info( "bundle digest in digest.json:\n%s", @@ -143,11 +143,13 @@ def bundles(self, build=None): run_command_with_process(f"npm run {_script}") logger.info("generate the `__init__.py` from template and versions") - with open(self._concat(self.main, "init.template")) as fp: + with open(self._concat(self.main, "init.template"), encoding="utf-8") as fp: t = string.Template(fp.read()) with open( - self._concat(self.deps_folder, os.pardir, "_dash_renderer.py"), "w" + self._concat(self.deps_folder, os.pardir, "_dash_renderer.py"), + "w", + encoding="utf-8", ) as fp: fp.write(t.safe_substitute(versions)) diff --git a/dash/development/component_generator.py b/dash/development/component_generator.py index a87eea9000..35824ba692 100644 --- a/dash/development/component_generator.py +++ b/dash/development/component_generator.py @@ -111,7 +111,7 @@ def generate_components( generator_methods = [functools.partial(generate_class_file, **py_generator_kwargs)] if rprefix is not None or jlprefix is not None: - with open("package.json", "r") as f: + with open("package.json", "r", encoding="utf-8") as f: pkg_data = safe_json_loads(f.read()) if rprefix is not None: @@ -120,7 +120,7 @@ def generate_components( if not os.path.exists("R"): os.makedirs("R") if os.path.isfile("dash-info.yaml"): - with open("dash-info.yaml") as yamldata: + with open("dash-info.yaml", encoding="utf-8") as yamldata: rpkg_data = yaml.safe_load(yamldata) else: rpkg_data = None @@ -135,7 +135,9 @@ def generate_components( components = generate_classes_files(project_shortname, metadata, *generator_methods) - with open(os.path.join(project_shortname, "metadata.json"), "w") as f: + with open( + os.path.join(project_shortname, "metadata.json"), "w", encoding="utf-8" + ) as f: json.dump(metadata, f, indent=2) generate_imports(project_shortname, components) diff --git a/dash/development/component_loader.py b/dash/development/component_loader.py index 352e100736..518c7638a4 100644 --- a/dash/development/component_loader.py +++ b/dash/development/component_loader.py @@ -13,7 +13,7 @@ def _get_metadata(metadata_path): # Start processing - with open(metadata_path) as data_file: + with open(metadata_path, encoding="utf-8") as data_file: json_string = data_file.read() data = json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode( json_string diff --git a/dash/development/update_components.py b/dash/development/update_components.py index b67d0a639e..fa6dee2c77 100644 --- a/dash/development/update_components.py +++ b/dash/development/update_components.py @@ -119,7 +119,7 @@ def build_components(components_source, concurrency): print(f"🚚 Moving build artifacts from {build_directory} to Dash 🚚") shutil.rmtree(dest_path) shutil.copytree(build_directory, dest_path) - with open(os.path.join(dest_path, ".gitkeep"), "w"): + with open(os.path.join(dest_path, ".gitkeep"), "w", encoding="utf-8"): pass print(f"🟢 Finished moving build artifacts from {build_directory} to Dash 🟢") diff --git a/dash/testing/application_runners.py b/dash/testing/application_runners.py index 8fccee063e..4dec8eda03 100644 --- a/dash/testing/application_runners.py +++ b/dash/testing/application_runners.py @@ -311,7 +311,7 @@ def start(self, app, start_timeout=2, cwd=None): logger.debug("content of the dashR app") logger.debug("%s", app) - with open(path, "w") as fp: + with open(path, "w", encoding="utf-8") as fp: fp.write(app) app = path @@ -408,7 +408,7 @@ def start(self, app, start_timeout=30, cwd=None): logger.debug("content of the Dash.jl app") logger.debug("%s", app) - with open(path, "w") as fp: + with open(path, "w", encoding="utf-8") as fp: fp.write(app) app = path diff --git a/setup.py b/setup.py index db44d08e7b..0581df2feb 100644 --- a/setup.py +++ b/setup.py @@ -2,11 +2,11 @@ from setuptools import setup, find_packages main_ns = {} -exec(open("dash/version.py").read(), main_ns) # pylint: disable=exec-used, consider-using-with +exec(open("dash/version.py", encoding="utf-8").read(), main_ns) # pylint: disable=exec-used, consider-using-with def read_req_file(req_type): - with open(f"requires-{req_type}.txt") as fp: + with open(f"requires-{req_type}.txt", encoding="utf-8") as fp: requires = (line.strip() for line in fp) return [req for req in requires if req and not req.startswith("#")] From 4b1d2202cc921c17230da16f23096cb0c5b800ac Mon Sep 17 00:00:00 2001 From: philippe Date: Wed, 13 Jul 2022 15:18:25 -0400 Subject: [PATCH 2/2] Update changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 116809d6bd..cfe49b03f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Fix use of the callback context in celery long callbacks. - Fix support of pattern matching for long callbacks. - [#2110](https://github.com/plotly/dash/pull/2110) Fix `dcc.Dropdown` search with component as prop for option label. +- [#2131](https://github.com/plotly/dash/pull/2131) Add encoding to file open calls. Fix bug [#2127](https://github.com/plotly/dash/issues/2127). ## Changed