From 8a2abb857b1f0c49ed4f6223947d20d6d722395c Mon Sep 17 00:00:00 2001 From: N3ther Date: Tue, 27 Aug 2024 05:38:07 -0400 Subject: [PATCH 1/5] added docstrings to parse_parentheses() and token_weights() --- comfy/sd1_clip.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py index 676653f777b..a1856030520 100644 --- a/comfy/sd1_clip.py +++ b/comfy/sd1_clip.py @@ -232,6 +232,27 @@ def load_sd(self, sd): return self.transformer.load_state_dict(sd, strict=False) def parse_parentheses(string): + """ + Split a string based off top-level nested parentheses. + + Parameters + ---------- + string : string + The string to be split into its top nested groups. + + Returns + ------- + result : list + A list of each element in string, split by top-level elements + + Examples + -------- + >>> string = "(foo)(bar)" + ['(foo)', '(bar)'] + + >>> string = "(foo(bar)(test1))(test2(test3))" + ['(foo(bar)(test1))', '(test2(test3))'] + """ result = [] current_item = "" nesting_level = 0 @@ -260,6 +281,55 @@ def parse_parentheses(string): return result def token_weights(string, current_weight): + """ + Find the requested weight of a token, and multiply it by the current weight. For parentheses groupings with no set weight, multiply by 1.1. + + Parameters + ---------- + string : string + The input of tokens to calculate requested weights for + current_weight : float + The current weight of all tokens + + Returns + ------- + out : list + A list of each token paired with the calculated weight + + Examples + -------- + >>> string = "(foo)" + >>> current_weight = 1.0 + [('foo', 1.1)] + + >>> string = "(foo)(bar)" + >>> current_weight = 1.0 + [('foo', 1.1), ('bar', 1.1)] + + >>> string = "(foo:2.0)" + >>> current_weight = 1.0 + [('foo', 2.0)] + + >>> string = "((foo))" + >>> current_weight = 1.0 + [('foo', 1.21)] + + >>> string = "((foo):1.1)" + >>> current_weight = 1.0 + [('foo', 1.21)] + + >>> string = "((foo:1.1))" + >>> current_weight = 1.0 + [('foo', 1.1)] + + >>> string = "(foo:0.0)" + >>> current_weight = 1.0 + [('foo', 0.0)] + + >>> string = "((foo:1.0):0.0)" + >>> current_weight = 1.0 + [('foo', 1.0)] + """ a = parse_parentheses(string) out = [] for x in a: @@ -267,6 +337,7 @@ def token_weights(string, current_weight): if len(x) >= 2 and x[-1] == ')' and x[0] == '(': x = x[1:-1] xx = x.rfind(":") + # This line makes *all nestings* multiply the weight by 1.1 weight *= 1.1 if xx > 0: try: From f787804bc8ff77b1eec83df6c6240f811e29f226 Mon Sep 17 00:00:00 2001 From: N3ther Date: Tue, 27 Aug 2024 13:33:15 -0400 Subject: [PATCH 2/5] added docstring for escape_important() and unescape_important() --- comfy/sd1_clip.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py index a1856030520..da57303b0d9 100644 --- a/comfy/sd1_clip.py +++ b/comfy/sd1_clip.py @@ -351,11 +351,55 @@ def token_weights(string, current_weight): return out def escape_important(text): + """ + Replace parentheses marked via backslashes with escape characters + + Parameters + ---------- + text : string + The string to have its important parentheses replaced + + Returns + ------- + text : string + The input string, with important parentheses replaced + + Examples + -------- + >>> text = "\\(foo\\)(bar)" + "\0\2foo\0\1(bar)" + + See Also + -------- + unescape_important : Replace escape characters with parentheses + """ text = text.replace("\\)", "\0\1") text = text.replace("\\(", "\0\2") return text def unescape_important(text): + """ + Replaces escape characters made via escape_important with parentheses + + Parameters + ---------- + text : string + The string to have its escape characters replaced + + Returns + ------- + text : string + The input string, with escape characters replaced + + Examples + -------- + >>> text = "\0\2foo\0\1(bar)" + "(foo)(bar)" + + See Also + -------- + escape_important: makes strings with the escape characters this function uses + """ text = text.replace("\0\1", ")") text = text.replace("\0\2", "(") return text From 0e101aa00d5929bb82e185197f24f79739f9127b Mon Sep 17 00:00:00 2001 From: N3ther Date: Tue, 27 Aug 2024 13:52:25 -0400 Subject: [PATCH 3/5] cleaned up docstrings --- comfy/sd1_clip.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py index da57303b0d9..17a26e595c0 100644 --- a/comfy/sd1_clip.py +++ b/comfy/sd1_clip.py @@ -237,7 +237,7 @@ def parse_parentheses(string): Parameters ---------- - string : string + string : str The string to be split into its top nested groups. Returns @@ -286,7 +286,7 @@ def token_weights(string, current_weight): Parameters ---------- - string : string + string : str The input of tokens to calculate requested weights for current_weight : float The current weight of all tokens @@ -329,6 +329,10 @@ def token_weights(string, current_weight): >>> string = "((foo:1.0):0.0)" >>> current_weight = 1.0 [('foo', 1.0)] + + Notes + ----- + All encapsulation will multiply a weight by 1.1 unless a weight is defined. """ a = parse_parentheses(string) out = [] @@ -356,12 +360,12 @@ def escape_important(text): Parameters ---------- - text : string + text : str The string to have its important parentheses replaced Returns ------- - text : string + text : str The input string, with important parentheses replaced Examples @@ -379,16 +383,16 @@ def escape_important(text): def unescape_important(text): """ - Replaces escape characters made via escape_important with parentheses + Replace escape characters made via escape_important with parentheses Parameters ---------- - text : string + text : str The string to have its escape characters replaced Returns ------- - text : string + text : str The input string, with escape characters replaced Examples @@ -424,6 +428,19 @@ def safe_load_embed_zip(embed_path): return out def expand_directory_list(directories): + """ + For all directories in a list, list all subdirectories beneath them + + Parameters + ---------- + directories : list + The list of directories to search for subdirectories with + + Returns + ------- + dirs : list + A list of all subdirectories found underneath the given directories + """ dirs = set() for x in directories: dirs.add(x) From a1bcc45da57625acb8dbae45f774dc406d4610fb Mon Sep 17 00:00:00 2001 From: N3ther Date: Tue, 27 Aug 2024 14:21:18 -0400 Subject: [PATCH 4/5] added more detail to token_weights() docstring --- comfy/sd1_clip.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py index 17a26e595c0..cfd3e0cfefc 100644 --- a/comfy/sd1_clip.py +++ b/comfy/sd1_clip.py @@ -330,9 +330,25 @@ def token_weights(string, current_weight): >>> current_weight = 1.0 [('foo', 1.0)] + >>> string = "foo ((((lol (cat:666) attack:100)))) baz" + >>> current_weight = 1.0 + [('foo ', 1.0), ('lol ', 100.0), ('cat', 666.0), (' attack', 100.0), (' baz', 1.0)] + + >>> string = "foo ((((lol (cat:666) attack):100))) baz" + >>> current_weight = 1.0 + [('foo ', 1.0), ('lol ', 110.0), ('cat', 666.0), (' attack', 110.0), (' baz', 1.0)] + Notes ----- - All encapsulation will multiply a weight by 1.1 unless a weight is defined. + See issue #4610 for more detail. One thing to note is that the default of 1.1 is multiplied + when there is no weight defined on the *interior* of the group instead of the exterior. This + behavior can be seen in the last two examples (thank you @jart for making these). In the first + example, the weight of 100 is defined inside the same parentheses grouping as both 'lol' and + 'attack'. There is no parentheses between the defined weight and the tokens, so there is no + multiplication of the weight by 1.1. In the second example, the weight is outside the parentheses + grouping, so the weights inside the grouping are first given a modifier of 1.1, then given a + modifier of 100. + """ a = parse_parentheses(string) out = [] From 19fd53dbb323777281a8a2a898265f034c6a9cc1 Mon Sep 17 00:00:00 2001 From: N3ther Date: Tue, 27 Aug 2024 22:25:05 -0400 Subject: [PATCH 5/5] fixed indentation --- comfy/sd1_clip.py | 294 +++++++++++++++++++++++----------------------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/comfy/sd1_clip.py b/comfy/sd1_clip.py index cfd3e0cfefc..6e9108f54db 100644 --- a/comfy/sd1_clip.py +++ b/comfy/sd1_clip.py @@ -232,27 +232,27 @@ def load_sd(self, sd): return self.transformer.load_state_dict(sd, strict=False) def parse_parentheses(string): - """ - Split a string based off top-level nested parentheses. - - Parameters - ---------- - string : str - The string to be split into its top nested groups. - - Returns - ------- - result : list - A list of each element in string, split by top-level elements - - Examples - -------- - >>> string = "(foo)(bar)" - ['(foo)', '(bar)'] - - >>> string = "(foo(bar)(test1))(test2(test3))" - ['(foo(bar)(test1))', '(test2(test3))'] - """ + """ + Split a string based off top-level nested parentheses. + + Parameters + ---------- + string : str + The string to be split into its top nested groups. + + Returns + ------- + result : list + A list of each element in string, split by top-level elements + + Examples + -------- + >>> string = "(foo)(bar)" + ['(foo)', '(bar)'] + + >>> string = "(foo(bar)(test1))(test2(test3))" + ['(foo(bar)(test1))', '(test2(test3))'] + """ result = [] current_item = "" nesting_level = 0 @@ -281,75 +281,75 @@ def parse_parentheses(string): return result def token_weights(string, current_weight): - """ - Find the requested weight of a token, and multiply it by the current weight. For parentheses groupings with no set weight, multiply by 1.1. - - Parameters - ---------- - string : str - The input of tokens to calculate requested weights for - current_weight : float - The current weight of all tokens - - Returns - ------- - out : list - A list of each token paired with the calculated weight - - Examples - -------- - >>> string = "(foo)" - >>> current_weight = 1.0 - [('foo', 1.1)] - - >>> string = "(foo)(bar)" - >>> current_weight = 1.0 - [('foo', 1.1), ('bar', 1.1)] - - >>> string = "(foo:2.0)" - >>> current_weight = 1.0 - [('foo', 2.0)] - - >>> string = "((foo))" - >>> current_weight = 1.0 - [('foo', 1.21)] - - >>> string = "((foo):1.1)" - >>> current_weight = 1.0 - [('foo', 1.21)] - - >>> string = "((foo:1.1))" - >>> current_weight = 1.0 - [('foo', 1.1)] - - >>> string = "(foo:0.0)" - >>> current_weight = 1.0 - [('foo', 0.0)] - - >>> string = "((foo:1.0):0.0)" - >>> current_weight = 1.0 - [('foo', 1.0)] - - >>> string = "foo ((((lol (cat:666) attack:100)))) baz" - >>> current_weight = 1.0 - [('foo ', 1.0), ('lol ', 100.0), ('cat', 666.0), (' attack', 100.0), (' baz', 1.0)] - - >>> string = "foo ((((lol (cat:666) attack):100))) baz" - >>> current_weight = 1.0 - [('foo ', 1.0), ('lol ', 110.0), ('cat', 666.0), (' attack', 110.0), (' baz', 1.0)] - - Notes - ----- - See issue #4610 for more detail. One thing to note is that the default of 1.1 is multiplied - when there is no weight defined on the *interior* of the group instead of the exterior. This - behavior can be seen in the last two examples (thank you @jart for making these). In the first - example, the weight of 100 is defined inside the same parentheses grouping as both 'lol' and - 'attack'. There is no parentheses between the defined weight and the tokens, so there is no - multiplication of the weight by 1.1. In the second example, the weight is outside the parentheses - grouping, so the weights inside the grouping are first given a modifier of 1.1, then given a - modifier of 100. - - """ + """ + Find the requested weight of a token, and multiply it by the current weight. For parentheses groupings with no set weight, multiply by 1.1. + + Parameters + ---------- + string : str + The input of tokens to calculate requested weights for + current_weight : float + The current weight of all tokens + + Returns + ------- + out : list + A list of each token paired with the calculated weight + + Examples + -------- + >>> string = "(foo)" + >>> current_weight = 1.0 + [('foo', 1.1)] + + >>> string = "(foo)(bar)" + >>> current_weight = 1.0 + [('foo', 1.1), ('bar', 1.1)] + + >>> string = "(foo:2.0)" + >>> current_weight = 1.0 + [('foo', 2.0)] + + >>> string = "((foo))" + >>> current_weight = 1.0 + [('foo', 1.21)] + + >>> string = "((foo):1.1)" + >>> current_weight = 1.0 + [('foo', 1.21)] + + >>> string = "((foo:1.1))" + >>> current_weight = 1.0 + [('foo', 1.1)] + + >>> string = "(foo:0.0)" + >>> current_weight = 1.0 + [('foo', 0.0)] + + >>> string = "((foo:1.0):0.0)" + >>> current_weight = 1.0 + [('foo', 1.0)] + + >>> string = "foo ((((lol (cat:666) attack:100)))) baz" + >>> current_weight = 1.0 + [('foo ', 1.0), ('lol ', 100.0), ('cat', 666.0), (' attack', 100.0), (' baz', 1.0)] + + >>> string = "foo ((((lol (cat:666) attack):100))) baz" + >>> current_weight = 1.0 + [('foo ', 1.0), ('lol ', 110.0), ('cat', 666.0), (' attack', 110.0), (' baz', 1.0)] + + Notes + ----- + See issue #4610 for more detail. One thing to note is that the default of 1.1 is multiplied + when there is no weight defined on the *interior* of the group instead of the exterior. This + behavior can be seen in the last two examples (thank you @jart for making these). In the first + example, the weight of 100 is defined inside the same parentheses grouping as both 'lol' and + 'attack'. There is no parentheses between the defined weight and the tokens, so there is no + multiplication of the weight by 1.1. In the second example, the weight is outside the parentheses + grouping, so the weights inside the grouping are first given a modifier of 1.1, then given a + modifier of 100. + + """ a = parse_parentheses(string) out = [] for x in a: @@ -371,55 +371,55 @@ def token_weights(string, current_weight): return out def escape_important(text): - """ - Replace parentheses marked via backslashes with escape characters - - Parameters - ---------- - text : str - The string to have its important parentheses replaced - - Returns - ------- - text : str - The input string, with important parentheses replaced - - Examples - -------- - >>> text = "\\(foo\\)(bar)" - "\0\2foo\0\1(bar)" - - See Also - -------- - unescape_important : Replace escape characters with parentheses - """ + """ + Replace parentheses marked via backslashes with escape characters + + Parameters + ---------- + text : str + The string to have its important parentheses replaced + + Returns + ------- + text : str + The input string, with important parentheses replaced + + Examples + -------- + >>> text = "\\(foo\\)(bar)" + "\0\2foo\0\1(bar)" + + See Also + -------- + unescape_important : Replace escape characters with parentheses + """ text = text.replace("\\)", "\0\1") text = text.replace("\\(", "\0\2") return text def unescape_important(text): - """ - Replace escape characters made via escape_important with parentheses - - Parameters - ---------- - text : str - The string to have its escape characters replaced - - Returns - ------- - text : str - The input string, with escape characters replaced - - Examples - -------- - >>> text = "\0\2foo\0\1(bar)" - "(foo)(bar)" - - See Also - -------- - escape_important: makes strings with the escape characters this function uses - """ + """ + Replace escape characters made via escape_important with parentheses + + Parameters + ---------- + text : str + The string to have its escape characters replaced + + Returns + ------- + text : str + The input string, with escape characters replaced + + Examples + -------- + >>> text = "\0\2foo\0\1(bar)" + "(foo)(bar)" + + See Also + -------- + escape_important: makes strings with the escape characters this function uses + """ text = text.replace("\0\1", ")") text = text.replace("\0\2", "(") return text @@ -444,19 +444,19 @@ def safe_load_embed_zip(embed_path): return out def expand_directory_list(directories): - """ - For all directories in a list, list all subdirectories beneath them - - Parameters - ---------- - directories : list - The list of directories to search for subdirectories with - - Returns - ------- - dirs : list - A list of all subdirectories found underneath the given directories - """ + """ + For all directories in a list, list all subdirectories beneath them + + Parameters + ---------- + directories : list + The list of directories to search for subdirectories with + + Returns + ------- + dirs : list + A list of all subdirectories found underneath the given directories + """ dirs = set() for x in directories: dirs.add(x)