Commit bd870b6cb9bce995cc99c71f39b80bcbacd59417
1 parent
8120a444
Add detailed docstrings for main methods in `generate_auto_job`.
Enhance clarity and maintainability by introducing comprehensive (AI generated) docstrings for methods in the `Main` class, detailing functionality, parameters, and return types.
Showing
2 changed files
with
277 additions
and
11 deletions
generate_auto_job
| @@ -157,6 +157,19 @@ def write_file(filename): | @@ -157,6 +157,19 @@ def write_file(filename): | ||
| 157 | 157 | ||
| 158 | 158 | ||
| 159 | class Main: | 159 | class Main: |
| 160 | + """ | ||
| 161 | + Main class to manage generation of files for QPDFJob. | ||
| 162 | + | ||
| 163 | + The class provides logic to determine changes in input or generated files, | ||
| 164 | + update checksums, and facilitate file generation based on specified options. | ||
| 165 | + It utilizes checksums to avoid unnecessary file regenerations and manages | ||
| 166 | + source files, output destinations, and their checks in a build process. | ||
| 167 | + | ||
| 168 | + :ivar SOURCES: List of source files used as inputs. | ||
| 169 | + :ivar DESTS: Dictionary mapping file identifiers to their output destinations. | ||
| 170 | + :ivar SUMS: Filename of the checksum file for source and destination file | ||
| 171 | + checksums. | ||
| 172 | + """ | ||
| 160 | # SOURCES is a list of source files whose contents are used by | 173 | # SOURCES is a list of source files whose contents are used by |
| 161 | # this program. If they change, we are out of date. | 174 | # this program. If they change, we are out of date. |
| 162 | SOURCES = [ | 175 | SOURCES = [ |
| @@ -209,6 +222,20 @@ class Main: | @@ -209,6 +222,20 @@ class Main: | ||
| 209 | return parser.parse_args(args) | 222 | return parser.parse_args(args) |
| 210 | 223 | ||
| 211 | def top(self, options): | 224 | def top(self, options): |
| 225 | + """ | ||
| 226 | + Processes a configuration job file and generates an appropriate output | ||
| 227 | + or performs checks based on the provided options. | ||
| 228 | + | ||
| 229 | + This function reads a 'job.yml' file to process configurations, generates | ||
| 230 | + declarations for option tables, and updates configuration destinations | ||
| 231 | + based on data from the job file. Depending on the mode specified in the | ||
| 232 | + options, it checks for modified input hashes, generates outputs, or exits | ||
| 233 | + with an appropriate message. | ||
| 234 | + | ||
| 235 | + :param options: The configuration options specifying the mode of operation | ||
| 236 | + (e.g., 'check', 'generate') and other relevant settings. | ||
| 237 | + :return: None | ||
| 238 | + """ | ||
| 212 | with open('job.yml', 'r') as f: | 239 | with open('job.yml', 'r') as f: |
| 213 | data = yaml.safe_load(f.read()) | 240 | data = yaml.safe_load(f.read()) |
| 214 | # config_decls maps a config key from an option in "options" | 241 | # config_decls maps a config key from an option in "options" |
| @@ -238,6 +265,19 @@ class Main: | @@ -238,6 +265,19 @@ class Main: | ||
| 238 | exit(f'{whoami} unknown mode') | 265 | exit(f'{whoami} unknown mode') |
| 239 | 266 | ||
| 240 | def get_hashes(self): | 267 | def get_hashes(self): |
| 268 | + """ | ||
| 269 | + Calculates and retrieves the SHA-256 hashes of files from source and destination paths. | ||
| 270 | + | ||
| 271 | + Summary: | ||
| 272 | + This method iterates over a collection of file paths from both source and | ||
| 273 | + destination attributes, calculates the SHA-256 hash for each existing file, | ||
| 274 | + and returns a dictionary containing the file paths and their corresponding | ||
| 275 | + hashes. If a file is not found, it is skipped. | ||
| 276 | + | ||
| 277 | + :return: A dictionary where keys are file paths (as str) and values are their | ||
| 278 | + SHA-256 hashes (as str). | ||
| 279 | + :rtype: dict | ||
| 280 | + """ | ||
| 241 | hashes = {} | 281 | hashes = {} |
| 242 | for i in sorted([*self.SOURCES, *self.DESTS.values()]): | 282 | for i in sorted([*self.SOURCES, *self.DESTS.values()]): |
| 243 | m = hashlib.sha256() | 283 | m = hashlib.sha256() |
| @@ -250,6 +290,19 @@ class Main: | @@ -250,6 +290,19 @@ class Main: | ||
| 250 | return hashes | 290 | return hashes |
| 251 | 291 | ||
| 252 | def check_hashes(self): | 292 | def check_hashes(self): |
| 293 | + """ | ||
| 294 | + Compares the current hashes with previously stored hashes in a file and determines if they match. | ||
| 295 | + | ||
| 296 | + This method retrieves the current hashes using the `get_hashes` method, attempts to read | ||
| 297 | + the stored hashes from a file, and compares the two. If there are mismatches or missing | ||
| 298 | + entries in any direction, relevant messages are printed. The purpose is to validate | ||
| 299 | + whether the current environment or configuration remains consistent with previous runs. | ||
| 300 | + | ||
| 301 | + :raises Exception: If an error occurs during file reading or processing. | ||
| 302 | + :return: A boolean value indicating whether the current hashes match the previously | ||
| 303 | + stored hashes. | ||
| 304 | + :rtype: bool | ||
| 305 | + """ | ||
| 253 | hashes = self.get_hashes() | 306 | hashes = self.get_hashes() |
| 254 | match = False | 307 | match = False |
| 255 | try: | 308 | try: |
| @@ -280,6 +333,18 @@ class Main: | @@ -280,6 +333,18 @@ class Main: | ||
| 280 | return match | 333 | return match |
| 281 | 334 | ||
| 282 | def update_hashes(self): | 335 | def update_hashes(self): |
| 336 | + """ | ||
| 337 | + Updates the hash values and writes them to a specified file. | ||
| 338 | + | ||
| 339 | + This method retrieves a collection of hash values by calling the `get_hashes` | ||
| 340 | + method. It then writes these hash values to a predefined file specified by | ||
| 341 | + the `SUMS` attribute. The file will include a header line indicating the | ||
| 342 | + source of the generated hashes. | ||
| 343 | + | ||
| 344 | + :raises IOError: If the file specified by `SUMS` cannot be opened | ||
| 345 | + or written to. | ||
| 346 | + :return: None | ||
| 347 | + """ | ||
| 283 | hashes = self.get_hashes() | 348 | hashes = self.get_hashes() |
| 284 | with open(self.SUMS, 'w') as f: | 349 | with open(self.SUMS, 'w') as f: |
| 285 | print(f'# Generated by {whoami}', file=f) | 350 | print(f'# Generated by {whoami}', file=f) |
| @@ -287,6 +352,23 @@ class Main: | @@ -287,6 +352,23 @@ class Main: | ||
| 287 | print(f'{k} {v}', file=f) | 352 | print(f'{k} {v}', file=f) |
| 288 | 353 | ||
| 289 | def generate_doc(self, df, f, f_man): | 354 | def generate_doc(self, df, f, f_man): |
| 355 | + """ | ||
| 356 | + Generates documentation and help-related functionalities for a given parser. | ||
| 357 | + | ||
| 358 | + This function processes input data to generate structured help content, associating | ||
| 359 | + it with topics or options. It splits the large function operation into smaller, manageable | ||
| 360 | + static sub-components, ensuring maintainability while dealing with large content. In addition | ||
| 361 | + to generating help texts for topics and options, it formats and outputs content into | ||
| 362 | + various formats including string outputs and man page style documentation. | ||
| 363 | + | ||
| 364 | + :param df: A file-like object from which content is read to generate topics | ||
| 365 | + and option-based help content. | ||
| 366 | + :param f: A writable file-like object where the generated static functions | ||
| 367 | + and help configuration for the parser are written. | ||
| 368 | + :param f_man: A writable file-like object where formatted manual page text | ||
| 369 | + is generated. | ||
| 370 | + :return: None | ||
| 371 | + """ | ||
| 290 | st_top = 0 | 372 | st_top = 0 |
| 291 | st_topic = 1 | 373 | st_topic = 1 |
| 292 | st_option = 2 | 374 | st_option = 2 |
| @@ -315,6 +397,18 @@ class Main: | @@ -315,6 +397,18 @@ class Main: | ||
| 315 | indent = ' ' * len(x) | 397 | indent = ' ' * len(x) |
| 316 | 398 | ||
| 317 | def append_long_text(line, topic): | 399 | def append_long_text(line, topic): |
| 400 | + """ | ||
| 401 | + Appends a line of text to a growing long text description for a specific topic. | ||
| 402 | + The function processes lines, either appending them to the existing long text | ||
| 403 | + or finalizing the long text for a topic if the line doesn't match the expected | ||
| 404 | + indentation. Raises an error if a finalized long text is missing for a given | ||
| 405 | + topic. Additionally, updates the collection of referenced topics if applicable. | ||
| 406 | + | ||
| 407 | + :param line: A string representing the current line of text being processed. | ||
| 408 | + :param topic: A string representing the topic associated with the long text. | ||
| 409 | + :return: A boolean indicating whether the long text for the topic has been | ||
| 410 | + finalized. | ||
| 411 | + """ | ||
| 318 | nonlocal indent, long_text | 412 | nonlocal indent, long_text |
| 319 | if line == '\n': | 413 | if line == '\n': |
| 320 | long_text += '\n' | 414 | long_text += '\n' |
| @@ -334,6 +428,20 @@ class Main: | @@ -334,6 +428,20 @@ class Main: | ||
| 334 | return False | 428 | return False |
| 335 | 429 | ||
| 336 | def manify(text): | 430 | def manify(text): |
| 431 | + """ | ||
| 432 | + Transforms a given text into a format suitable for a manual page. | ||
| 433 | + | ||
| 434 | + This function processes the input text and modifies its formatting | ||
| 435 | + to match the conventions typically used in manual pages. It converts | ||
| 436 | + list items that start with '- ' into equivalent `.IP \\[bu]` formatted | ||
| 437 | + entries and handles indented lines associated with such list items. | ||
| 438 | + | ||
| 439 | + :param text: The input plain text to be transformed for manual page | ||
| 440 | + formatting. | ||
| 441 | + :type text: str | ||
| 442 | + :return: The modified text formatted for manual pages. | ||
| 443 | + :rtype: str | ||
| 444 | + """ | ||
| 337 | lines = text.split('\n') | 445 | lines = text.split('\n') |
| 338 | out = [] | 446 | out = [] |
| 339 | last_was_item = False | 447 | last_was_item = False |
| @@ -447,6 +555,17 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -447,6 +555,17 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 447 | ', '.join(self.options_without_help)) | 555 | ', '.join(self.options_without_help)) |
| 448 | 556 | ||
| 449 | def generate(self, data): | 557 | def generate(self, data): |
| 558 | + """ | ||
| 559 | + Generates and writes various files associated with job configuration, initialization, schema, | ||
| 560 | + documentation, and other related tasks. The method performs necessary validations, extracts | ||
| 561 | + version information, processes job configurations, and prepares structured outputs for different | ||
| 562 | + file types. It ensures completeness of help options and updates necessary data hashes. | ||
| 563 | + | ||
| 564 | + :param data: Input data required for generating and preparing files. | ||
| 565 | + :type data: any | ||
| 566 | + | ||
| 567 | + :return: None | ||
| 568 | + """ | ||
| 450 | warn(f'{whoami}: regenerating auto job files') | 569 | warn(f'{whoami}: regenerating auto job files') |
| 451 | self.validate(data) | 570 | self.validate(data) |
| 452 | 571 | ||
| @@ -521,9 +640,23 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -521,9 +640,23 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 521 | # DON'T ADD CODE TO generate AFTER update_hashes | 640 | # DON'T ADD CODE TO generate AFTER update_hashes |
| 522 | 641 | ||
| 523 | def handle_trivial(self, i, identifier, cfg, prefix, kind, v): | 642 | def handle_trivial(self, i, identifier, cfg, prefix, kind, v): |
| 524 | - # A "trivial" option is one whose handler does nothing other | ||
| 525 | - # than to call the config method with the same name (switched | ||
| 526 | - # to camelCase). | 643 | + """ |
| 644 | + Handle a "trivial" option by generating initialization and declaration statements for configuration methods. | ||
| 645 | + A trivial option is one where the handler does nothing other than calling the | ||
| 646 | + configuration method with the same name (switched to camelCase). | ||
| 647 | + | ||
| 648 | + The function processes different option types (`bare`, `required_parameter`, `optional_parameter`, | ||
| 649 | + `required_choices`, `optional_choices`) and generates corresponding initialization code for adding | ||
| 650 | + these options. It also generates or updates configuration method declarations as needed. | ||
| 651 | + | ||
| 652 | + :param i: Identifier of the option. | ||
| 653 | + :param identifier: Name of the configuration method to be invoked. | ||
| 654 | + :param cfg: Object representing the configuration context. | ||
| 655 | + :param prefix: Prefix used for generating configuration method names. | ||
| 656 | + :param kind: Type of the option (e.g., "bare", "required_parameter", etc.). | ||
| 657 | + :param v: Additional value or information associated with specific types of options. | ||
| 658 | + :return: None | ||
| 659 | + """ | ||
| 527 | decl_arg = 1 | 660 | decl_arg = 1 |
| 528 | decl_arg_optional = False | 661 | decl_arg_optional = False |
| 529 | if kind == 'bare': | 662 | if kind == 'bare': |
| @@ -576,10 +709,29 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -576,10 +709,29 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 576 | f'QPDF_DLL {config_prefix}* {identifier}();') | 709 | f'QPDF_DLL {config_prefix}* {identifier}();') |
| 577 | 710 | ||
| 578 | def handle_flag(self, i, identifier, kind, v): | 711 | def handle_flag(self, i, identifier, kind, v): |
| 579 | - # For flags that require manual handlers, declare the handler | ||
| 580 | - # and register it. They have to be implemented manually in | ||
| 581 | - # QPDFJob_argv.cc. You get compiler/linker errors for any | ||
| 582 | - # missing methods. | 712 | + """ |
| 713 | + Handles flag processing and declaration for commands that require custom | ||
| 714 | + manual handlers. Depending on the type of the flag, it declares the | ||
| 715 | + appropriate handler method and registers it. They have to be implemented | ||
| 716 | + manually in QPDFJob_argv.cc. You get compiler/linker errors for any | ||
| 717 | + missing methods.This function associates the flag identifier with specific | ||
| 718 | + handlers for various flag types such as bare, parameter-based, or | ||
| 719 | + choice-based flags. | ||
| 720 | + | ||
| 721 | + :param i: The command-line flag or parameter. | ||
| 722 | + :type i: str | ||
| 723 | + :param identifier: Name used to identify the flag handler method. | ||
| 724 | + :type identifier: str | ||
| 725 | + :param kind: The type of flag. Supported types are 'bare', | ||
| 726 | + 'required_parameter', 'optional_parameter', | ||
| 727 | + 'required_choices', or 'optional_choices'. | ||
| 728 | + :type kind: str | ||
| 729 | + :param v: Additional value or information required for choices or | ||
| 730 | + parameter flags; unused in the case of 'bare' flags. | ||
| 731 | + :type v: str | ||
| 732 | + :return: None | ||
| 733 | + :rtype: None | ||
| 734 | + """ | ||
| 583 | if kind == 'bare': | 735 | if kind == 'bare': |
| 584 | self.decls.append(f'void {identifier}();') | 736 | self.decls.append(f'void {identifier}();') |
| 585 | self.init.append(f'this->ap.addBare("{i}", ' | 737 | self.init.append(f'this->ap.addBare("{i}", ' |
| @@ -605,6 +757,20 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -605,6 +757,20 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 605 | f', false, {v}_choices);') | 757 | f', false, {v}_choices);') |
| 606 | 758 | ||
| 607 | def prepare(self, data): | 759 | def prepare(self, data): |
| 760 | + """ | ||
| 761 | + Prepare the internal configuration of options and handlers for argument parsing. | ||
| 762 | + | ||
| 763 | + This function sets up various internal data structures essential for managing | ||
| 764 | + argv handlers, option table declarations, initialization procedures, and other | ||
| 765 | + required data for parsing command-line arguments. It also assists in registering | ||
| 766 | + handlers, generating constants, and organizing choices for easier use in the | ||
| 767 | + argument parsing process. | ||
| 768 | + | ||
| 769 | + :param data: The input dictionary containing configuration for options, choices, | ||
| 770 | + and other relevant details to initialize argument parsing. | ||
| 771 | + :type data: dict | ||
| 772 | + :return: None | ||
| 773 | + """ | ||
| 608 | self.decls = [] # argv handler declarations | 774 | self.decls = [] # argv handler declarations |
| 609 | self.init = [] # initialize arg parsing code | 775 | self.init = [] # initialize arg parsing code |
| 610 | self.json_decls = [] # json handler declarations | 776 | self.json_decls = [] # json handler declarations |
| @@ -613,9 +779,20 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -613,9 +779,20 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 613 | self.by_table = {} # table information by name for easy lookup | 779 | self.by_table = {} # table information by name for easy lookup |
| 614 | 780 | ||
| 615 | def add_jdata(flag, table, details): | 781 | def add_jdata(flag, table, details): |
| 616 | - # Keep track of each flag and where it appears so we can | ||
| 617 | - # check consistency between the json information and the | ||
| 618 | - # options section. | 782 | + """ |
| 783 | + Add JSON data to track flags and their respective details and table associations. | ||
| 784 | + | ||
| 785 | + This function manages the relationship between a given flag and the | ||
| 786 | + tables it references. It also ensures that appropriate options are | ||
| 787 | + added if the table specified is "help". For other tables, it maintains | ||
| 788 | + the corresponding details against the flag in the JSON structure. | ||
| 789 | + | ||
| 790 | + :param flag: A string identifying a specific flag for tracking. | ||
| 791 | + :param table: A string specifying the table the flag is associated with. | ||
| 792 | + :param details: A dictionary containing details associated with the given table | ||
| 793 | + for the specified flag. | ||
| 794 | + :return: None | ||
| 795 | + """ | ||
| 619 | nonlocal self | 796 | nonlocal self |
| 620 | if table == 'help': | 797 | if table == 'help': |
| 621 | self.help_options.add(f'--{flag}') | 798 | self.help_options.add(f'--{flag}') |
| @@ -730,6 +907,16 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -730,6 +907,16 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 730 | self.decls.append(f'void {identifier}();') | 907 | self.decls.append(f'void {identifier}();') |
| 731 | 908 | ||
| 732 | def handle_json_trivial(self, flag_key, fdata): | 909 | def handle_json_trivial(self, flag_key, fdata): |
| 910 | + """ | ||
| 911 | + Handles JSON configuration based on the specified flag, data, and the associated | ||
| 912 | + table configuration. Determines the type of operation based on the kind of entry | ||
| 913 | + and appends the appropriate initialization string to the `json_init`. | ||
| 914 | + | ||
| 915 | + :param flag_key: A string representing the key used to modify the configuration. | ||
| 916 | + :param fdata: A dictionary containing table information and other associated | ||
| 917 | + data necessary for configuration handling. | ||
| 918 | + :return: None | ||
| 919 | + """ | ||
| 733 | config = None | 920 | config = None |
| 734 | for t, [kind, v] in fdata['tables'].items(): | 921 | for t, [kind, v] in fdata['tables'].items(): |
| 735 | # We have determined that all tables, if multiple, have | 922 | # We have determined that all tables, if multiple, have |
| @@ -758,6 +945,14 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -758,6 +945,14 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 758 | f' {{ {config}->{flag_key}(p); }});') | 945 | f' {{ {config}->{flag_key}(p); }});') |
| 759 | 946 | ||
| 760 | def handle_json_manual(self, path): | 947 | def handle_json_manual(self, path): |
| 948 | + """ | ||
| 949 | + Processes a given file path to create a method name in camelCase format | ||
| 950 | + and appends corresponding declarations and invocation to internal lists. | ||
| 951 | + | ||
| 952 | + :param path: The file path to process as a string | ||
| 953 | + :type path: str | ||
| 954 | + :return: None | ||
| 955 | + """ | ||
| 761 | method = re.sub(r'\.([a-zA-Z0-9])', | 956 | method = re.sub(r'\.([a-zA-Z0-9])', |
| 762 | lambda x: x.group(1).upper(), | 957 | lambda x: x.group(1).upper(), |
| 763 | f'setup{path}') | 958 | f'setup{path}') |
| @@ -874,6 +1069,27 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -874,6 +1069,27 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 874 | return schema_value | 1069 | return schema_value |
| 875 | 1070 | ||
| 876 | def generate_schema(self, data): | 1071 | def generate_schema(self, data): |
| 1072 | + """ | ||
| 1073 | + Generate and validate a JSON schema based on the given data. | ||
| 1074 | + | ||
| 1075 | + This method ensures that every command-line option is represented | ||
| 1076 | + in the JSON schema described in the `data` parameter. It checks | ||
| 1077 | + for consistency between the defined command-line options and the | ||
| 1078 | + JSON section of the input data. If any option is missing or | ||
| 1079 | + inconsistent, an exception is raised. The method builds a schema | ||
| 1080 | + by incorporating help information provided in the data, and it | ||
| 1081 | + registers JSON handlers that correspond with the created schema. | ||
| 1082 | + | ||
| 1083 | + :param data: A dictionary containing the JSON section and option | ||
| 1084 | + information necessary for schema generation and | ||
| 1085 | + validation. | ||
| 1086 | + - `data['json']`: Dictionary describing the JSON | ||
| 1087 | + schema structure. | ||
| 1088 | + :return: None | ||
| 1089 | + :raises Exception: If there is a mismatch between expected | ||
| 1090 | + options and options specified in the JSON | ||
| 1091 | + schema. | ||
| 1092 | + """ | ||
| 877 | # Check to make sure that every command-line option is | 1093 | # Check to make sure that every command-line option is |
| 878 | # represented in data['json']. Build a list of options that we | 1094 | # represented in data['json']. Build a list of options that we |
| 879 | # expect. If an option appears once, we just expect to see it | 1095 | # expect. If an option appears once, we just expect to see it |
| @@ -914,6 +1130,21 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -914,6 +1130,21 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 914 | str(set(expected.keys()) - options_seen)) | 1130 | str(set(expected.keys()) - options_seen)) |
| 915 | 1131 | ||
| 916 | def check_keys(self, what, d, exp): | 1132 | def check_keys(self, what, d, exp): |
| 1133 | + """ | ||
| 1134 | + Validates that the provided dictionary has the expected set of keys. If the | ||
| 1135 | + `d` parameter is not a dictionary or contains unknown keys that are not | ||
| 1136 | + in the `exp` set, the program will terminate with an error message. | ||
| 1137 | + | ||
| 1138 | + :param what: A descriptive string indicating the purpose of the dictionary. | ||
| 1139 | + Used in error messages to provide context. | ||
| 1140 | + :type what: str | ||
| 1141 | + :param d: The dictionary to be inspected for its keys. | ||
| 1142 | + :type d: dict | ||
| 1143 | + :param exp: A set of expected keys that `d` should adhere to. | ||
| 1144 | + :type exp: set | ||
| 1145 | + :return: None. Terminates the program with an error message if the | ||
| 1146 | + validation fails. | ||
| 1147 | + """ | ||
| 917 | if not isinstance(d, dict): | 1148 | if not isinstance(d, dict): |
| 918 | exit(f'{what} is not a dictionary') | 1149 | exit(f'{what} is not a dictionary') |
| 919 | actual = set(d.keys()) | 1150 | actual = set(d.keys()) |
| @@ -922,6 +1153,22 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -922,6 +1153,22 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 922 | exit(f'{what}: unknown keys = {extra}') | 1153 | exit(f'{what}: unknown keys = {extra}') |
| 923 | 1154 | ||
| 924 | def validate(self, data): | 1155 | def validate(self, data): |
| 1156 | + """ | ||
| 1157 | + Validates the given data against a set of required keys for proper structure. Checks are | ||
| 1158 | + performed for both the top-level keys and the keys within the 'options' list in the data. | ||
| 1159 | + This ensures that the data has the required configuration necessary for processing. | ||
| 1160 | + | ||
| 1161 | + :param data: The input data to be validated. It is expected to be a dictionary containing | ||
| 1162 | + the keys 'choices', 'options', and 'json'. The 'options' key must contain a list | ||
| 1163 | + whose elements are dictionaries with specific required keys. | ||
| 1164 | + :type data: dict | ||
| 1165 | + :return: None. The function does not return any value but may raise exceptions if the | ||
| 1166 | + validation fails. | ||
| 1167 | + :rtype: None | ||
| 1168 | + :raises ValueError: If any required keys are missing in the provided data for either the | ||
| 1169 | + top-level or within the 'options' list. | ||
| 1170 | + :raises TypeError: If the structure or type of the input 'data' is incorrect. | ||
| 1171 | + """ | ||
| 925 | self.check_keys('top', data, set( | 1172 | self.check_keys('top', data, set( |
| 926 | ['choices', 'options', 'json'])) | 1173 | ['choices', 'options', 'json'])) |
| 927 | for o in data['options']: | 1174 | for o in data['options']: |
| @@ -932,6 +1179,25 @@ A complete manual can be found at https://qpdf.readthedocs.io. | @@ -932,6 +1179,25 @@ A complete manual can be found at https://qpdf.readthedocs.io. | ||
| 932 | 'required_choices', 'optional_choices'])) | 1179 | 'required_choices', 'optional_choices'])) |
| 933 | 1180 | ||
| 934 | def to_identifier(self, label, prefix, const): | 1181 | def to_identifier(self, label, prefix, const): |
| 1182 | + """ | ||
| 1183 | + Converts a given label into a valid identifier by replacing invalid characters | ||
| 1184 | + and applying formatting rules. The method ensures that the resulting identifier | ||
| 1185 | + conforms to naming conventions, optionally prepending a prefix and enforcing | ||
| 1186 | + uppercase for constants. | ||
| 1187 | + | ||
| 1188 | + :param label: The input label string that needs to be converted into an | ||
| 1189 | + identifier. | ||
| 1190 | + :type label: str | ||
| 1191 | + :param prefix: An optional prefix to prepend to the identifier. If not | ||
| 1192 | + provided, no prefix is added. | ||
| 1193 | + :type prefix: str | ||
| 1194 | + :param const: Indicates whether the output identifier should be treated as | ||
| 1195 | + a constant. If True, the identifier is converted to uppercase and prefixed. | ||
| 1196 | + :type const: bool | ||
| 1197 | + :return: A valid identifier string generated from the input label based on the | ||
| 1198 | + provided parameters. | ||
| 1199 | + :rtype: str | ||
| 1200 | + """ | ||
| 935 | identifier = re.sub(r'[^a-zA-Z0-9]', '_', label) | 1201 | identifier = re.sub(r'[^a-zA-Z0-9]', '_', label) |
| 936 | if const: | 1202 | if const: |
| 937 | identifier = f'{prefix}_{identifier.upper()}' | 1203 | identifier = f'{prefix}_{identifier.upper()}' |
job.sums
| 1 | # Generated by generate_auto_job | 1 | # Generated by generate_auto_job |
| 2 | CMakeLists.txt 18214e276670dc8beb2ab83f789c6d94941bc92b199b353f3943024cfd41d3bc | 2 | CMakeLists.txt 18214e276670dc8beb2ab83f789c6d94941bc92b199b353f3943024cfd41d3bc |
| 3 | -generate_auto_job f64733b79dcee5a0e3e8ccc6976448e8ddf0e8b6529987a66a7d3ab2ebc10a86 | 3 | +generate_auto_job 280b75d5307c537385a75ec588493496cfb0bc754d48c34ca8c42bbc55dd717b |
| 4 | include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf225099ee42bc5bb4 | 4 | include/qpdf/auto_job_c_att.hh 4c2b171ea00531db54720bf49a43f8b34481586ae7fb6cbf225099ee42bc5bb4 |
| 5 | include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42 | 5 | include/qpdf/auto_job_c_copy_att.hh 50609012bff14fd82f0649185940d617d05d530cdc522185c7f3920a561ccb42 |
| 6 | include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5 | 6 | include/qpdf/auto_job_c_enc.hh 28446f3c32153a52afa239ea40503e6cc8ac2c026813526a349e0cd4ae17ddd5 |