From 37e9aa9f94e729b612f2cb3e8778ff73b6d3f00f Mon Sep 17 00:00:00 2001 From: LarryWoestman Date: Sat, 30 Jul 2022 12:19:52 -0700 Subject: [PATCH] Path: Added type annotations along with some refactoring. --- src/Mod/Path/Path/Post/UtilsArguments.py | 72 ++++++++++---- .../Path/Post/scripts/refactored_test_post.py | 96 +++++++++++-------- .../Path/PathTests/TestRefactoredTestPost.py | 10 +- 3 files changed, 117 insertions(+), 61 deletions(-) diff --git a/src/Mod/Path/Path/Post/UtilsArguments.py b/src/Mod/Path/Path/Post/UtilsArguments.py index 3019821afd..55206ace92 100644 --- a/src/Mod/Path/Path/Post/UtilsArguments.py +++ b/src/Mod/Path/Path/Post/UtilsArguments.py @@ -33,21 +33,30 @@ These are functions related to arguments and values for creating custom post pro import argparse import os import shlex +from typing import Any, Callable, Dict from FreeCAD import Units import Path.Post.UtilsParse as PostUtilsParse +# Define some types that are used throughout this file +PathParameter = float +PathParameters = Dict[str, PathParameter] +Parser = argparse.ArgumentParser +Values = Dict[str, Any] + +ParameterFunction = Callable[[Values, str, str, PathParameter, PathParameters], str] + def add_flag_type_arguments( argument_group, - default_flag, - true_argument, - false_argument, - true_help, - false_help, - visible=True, -): + default_flag: bool, + true_argument: str, + false_argument: str, + true_help: str, + false_help: str, + visible: bool = True, +) -> None: """Create an argument specification for an argument that is a flag.""" if visible: if default_flag: @@ -60,7 +69,7 @@ def add_flag_type_arguments( argument_group.add_argument(false_argument, action="store_true", help=false_help) -def init_argument_defaults(argument_defaults): +def init_argument_defaults(argument_defaults: Dict[str, bool]) -> None: """Initialize which argument to show as the default in flag-type arguments.""" argument_defaults["axis-modal"] = False argument_defaults["bcnc"] = False @@ -77,7 +86,7 @@ def init_argument_defaults(argument_defaults): argument_defaults["translate_drill"] = False -def init_arguments_visible(arguments_visible): +def init_arguments_visible(arguments_visible: Dict[str, bool]) -> None: """Initialize the flags for which arguments are visible in the arguments tooltip.""" arguments_visible["bcnc"] = False arguments_visible["axis-modal"] = True @@ -101,12 +110,19 @@ def init_arguments_visible(arguments_visible): arguments_visible["wait-for-spindle"] = False -def init_shared_arguments(values, argument_defaults, arguments_visible): +def init_shared_arguments( + values: Values, + argument_defaults: Dict[str, bool], + arguments_visible: Dict[str, bool], +) -> Parser: """Initialize the arguments for postprocessors.""" + help_message: str + parser: Parser + parser = argparse.ArgumentParser( prog=values["MACHINE_NAME"], usage=argparse.SUPPRESS, add_help=False ) - shared = parser.add_argument_group("Arguments that are commonly used") + shared = parser.add_argument_group("Arguments that are commonly used") # type: ignore add_flag_type_arguments( shared, argument_defaults["metric_inches"], @@ -283,7 +299,7 @@ def init_shared_arguments(values, argument_defaults, arguments_visible): return parser -def init_shared_values(values): +def init_shared_values(values: Values): """Initialize the default values in postprocessors.""" # # The starting axis precision is 3 digits after the decimal point. @@ -294,6 +310,7 @@ def init_shared_values(values): # with a G73 command. # values["CHIPBREAKING_AMOUNT"] = Units.Quantity(0.25, Units.Length) + # # If this is set to "", all spaces are removed from between commands and parameters. # @@ -306,9 +323,9 @@ def init_shared_values(values): # # Variables storing the current position for the drill_translate routine. # - values["CURRENT_X"] = 0 - values["CURRENT_Y"] = 0 - values["CURRENT_Z"] = 0 + values["CURRENT_X"] = 0.0 + values["CURRENT_Y"] = 0.0 + values["CURRENT_Z"] = 0.0 # # Default axis precision for metric is 3 digits after the decimal point. # (see http://linuxcnc.org/docs/2.7/html/gcode/overview.html#_g_code_best_practices) @@ -573,20 +590,39 @@ def init_shared_values(values): values["USE_TLO"] = True -def process_shared_arguments(values, parser, argstring, all_visible, filename): +def process_shared_arguments( + values: Values, + parser: Parser, + argstring: str, + all_visible: Parser, + filename: str, +): """Process the arguments to the postprocessor.""" + argument_text: str + v: str + try: args = parser.parse_args(shlex.split(argstring)) if args.output_all_arguments: argument_text = all_visible.format_help() if not filename == "-": - with open(filename, "w", newline=values["END_OF_LINE_CHARACTERS"]) as f: + with open( + filename, + "w", + encoding="utf-8", + newline=values["END_OF_LINE_CHARACTERS"], + ) as f: f.write(argument_text) return (False, argument_text) if args.output_visible_arguments: argument_text = parser.format_help() if not filename == "-": - with open(filename, "w", newline=values["END_OF_LINE_CHARACTERS"]) as f: + with open( + filename, + "w", + encoding="utf-8", + newline=values["END_OF_LINE_CHARACTERS"], + ) as f: f.write(argument_text) return (False, argument_text) # Default to metric unless an argument overrides it diff --git a/src/Mod/Path/Path/Post/scripts/refactored_test_post.py b/src/Mod/Path/Path/Post/scripts/refactored_test_post.py index 50b20cf9c9..d49d549b1c 100644 --- a/src/Mod/Path/Path/Post/scripts/refactored_test_post.py +++ b/src/Mod/Path/Path/Post/scripts/refactored_test_post.py @@ -23,8 +23,16 @@ # *************************************************************************** -import Path.Post.UtilsArguments as PostUtilsArguments -import Path.Post.UtilsExport as PostUtilsExport +import argparse + +from typing import Any, Dict, Union + +import Path.Post.UtilsArguments as UtilsArguments +import Path.Post.UtilsExport as UtilsExport + +# Define some types that are used throughout this file +Parser = argparse.ArgumentParser +Values = Dict[str, Any] # # The following variables need to be global variables @@ -38,8 +46,8 @@ import Path.Post.UtilsExport as PostUtilsExport # need to be defined before the "init_shared_arguments" routine can be # called to create TOOLTIP_ARGS, so they also end up having to be globals. # -TOOLTIP = """This is a postprocessor file for the Path workbench. It is used to -test the postprocessor code. It probably isn't useful for "real" G-code. +TOOLTIP: str = """This is a postprocessor file for the Path workbench. It is used to +test the postprocessor code. It probably isn't useful for "real" gcode. import refactored_test_post refactored_test_post.export(object,"/path/to/file.ncc","") @@ -47,15 +55,15 @@ refactored_test_post.export(object,"/path/to/file.ncc","") # # Default to metric mode # -UNITS = "G21" +UNITS: str = "G21" -def init_values(values): +def init_values(values: Values) -> None: """Initialize values that are used throughout the postprocessor.""" # global UNITS - PostUtilsArguments.init_shared_values(values) + UtilsArguments.init_shared_values(values) # # Set any values here that need to override the default values set # in the init_shared_values routine. @@ -105,9 +113,9 @@ def init_values(values): values["UNITS"] = UNITS -def init_argument_defaults(argument_defaults): +def init_argument_defaults(argument_defaults: Dict[str, bool]) -> None: """Initialize which arguments (in a pair) are shown as the default argument.""" - PostUtilsArguments.init_argument_defaults(argument_defaults) + UtilsArguments.init_argument_defaults(argument_defaults) # # Modify which argument to show as the default in flag-type arguments here. # If the value is True, the first argument will be shown as the default. @@ -125,22 +133,30 @@ def init_argument_defaults(argument_defaults): # -def init_arguments_visible(arguments_visible): +def init_arguments_visible(arguments_visible: Dict[str, bool]) -> None: """Initialize which argument pairs are visible in TOOLTIP_ARGS.""" - PostUtilsArguments.init_arguments_visible(arguments_visible) + key: str + + UtilsArguments.init_arguments_visible(arguments_visible) # # Modify the visibility of any arguments from the defaults here. # # # Make all arguments invisible by default. # - for k in iter(arguments_visible): - arguments_visible[k] = False + for key in iter(arguments_visible): + arguments_visible[key] = False -def init_arguments(values, argument_defaults, arguments_visible): +def init_arguments( + values: Values, + argument_defaults: Dict[str, bool], + arguments_visible: Dict[str, bool], +) -> Parser: """Initialize the shared argument definitions.""" - parser = PostUtilsArguments.init_shared_arguments( + parser: Parser + + parser = UtilsArguments.init_shared_arguments( values, argument_defaults, arguments_visible ) # @@ -154,42 +170,46 @@ def init_arguments(values, argument_defaults, arguments_visible): # Creating global variables and using functions to modify them # is useful for being able to test things later. # -values = {} -init_values(values) -argument_defaults = {} -init_argument_defaults(argument_defaults) -arguments_visible = {} -init_arguments_visible(arguments_visible) -parser = init_arguments(values, argument_defaults, arguments_visible) +global_values: Values = {} +init_values(global_values) +global_argument_defaults: Dict[str, bool] = {} +init_argument_defaults(global_argument_defaults) +global_arguments_visible: Dict[str, bool] = {} +init_arguments_visible(global_arguments_visible) +global_parser: Parser = init_arguments( + global_values, global_argument_defaults, global_arguments_visible +) # # The TOOLTIP_ARGS value is created from the help information about the arguments. # -TOOLTIP_ARGS = parser.format_help() +TOOLTIP_ARGS = global_parser.format_help() # # Create another parser just to get a list of all possible arguments # that may be output using --output_all_arguments. # -all_arguments_visible = {} -for k in iter(arguments_visible): - all_arguments_visible[k] = True -all_visible = init_arguments(values, argument_defaults, all_arguments_visible) +global_all_arguments_visible: Dict[str, bool] = {} +k: str +for k in iter(global_arguments_visible): + global_all_arguments_visible[k] = True +global_all_visible: Parser = init_arguments( + global_values, global_argument_defaults, global_all_arguments_visible +) -def export(objectslist, filename, argstring): +def export(objectslist, filename: str, argstring: str) -> str: """Postprocess the objects in objectslist to filename.""" - # - global all_visible - global parser - global UNITS - global values + args: Union[str, argparse.Namespace] + flag: bool + + global UNITS # pylint: disable=global-statement # print(parser.format_help()) - (flag, args) = PostUtilsArguments.process_shared_arguments( - values, parser, argstring, all_visible, filename + (flag, args) = UtilsArguments.process_shared_arguments( + global_values, global_parser, argstring, global_all_visible, filename ) if not flag: - return args + return args # type: ignore # # Process any additional arguments here # @@ -198,6 +218,6 @@ def export(objectslist, filename, argstring): # Update the global variables that might have been modified # while processing the arguments. # - UNITS = values["UNITS"] + UNITS = global_values["UNITS"] - return PostUtilsExport.export_common(values, objectslist, filename) + return UtilsExport.export_common(global_values, objectslist, filename) diff --git a/src/Mod/Path/PathTests/TestRefactoredTestPost.py b/src/Mod/Path/PathTests/TestRefactoredTestPost.py index b75a0e7a6b..f393de51fe 100644 --- a/src/Mod/Path/PathTests/TestRefactoredTestPost.py +++ b/src/Mod/Path/PathTests/TestRefactoredTestPost.py @@ -76,7 +76,7 @@ class TestRefactoredTestPost(PathTestUtils.PathTestBase): # Re-initialize all of the values before doing a test. # postprocessor.UNITS = "G21" - postprocessor.init_values(postprocessor.values) + postprocessor.init_values(postprocessor.global_values) def tearDown(self): """tearDown()... @@ -1029,7 +1029,7 @@ G90 # # Re-initialize all of the values before doing more tests. # - postprocessor.init_values(postprocessor.values) + postprocessor.init_values(postprocessor.global_values) # # Test translate_drill with G83 and G91. path = [ @@ -1180,7 +1180,7 @@ G90 # # Re-initialize all of the values before doing more tests. # - postprocessor.init_values(postprocessor.values) + postprocessor.init_values(postprocessor.global_values) # # Test translate_drill with G81 and G91. path = [ @@ -1315,7 +1315,7 @@ G90 # # Re-initialize all of the values before doing more tests. # - postprocessor.init_values(postprocessor.values) + postprocessor.init_values(postprocessor.global_values) # # Test translate_drill with G82 and G91. path = [ @@ -1468,7 +1468,7 @@ G90 # # Re-initialize all of the values before doing more tests. # - postprocessor.init_values(postprocessor.values) + postprocessor.init_values(postprocessor.global_values) # # Test translate_drill with G83 and G91. path = [