Skip to content

Commit b53e6b5

Browse files
committed
feat: improve regex for variable formatting
1 parent d4303f9 commit b53e6b5

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

promptfile/reader.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,31 @@ def format(self, **kwargs) -> "PromptConfig":
6767
for i, msg in enumerate(new.messages):
6868
content = msg["content"]
6969
try:
70-
# Use a single format call with all kwargs
7170
msg["content"] = content.format(**kwargs)
7271
except KeyError as e:
73-
# If KeyError occurs, fall back to manual replacement
7472
missing_keys = []
75-
for key, value in kwargs.items():
76-
if f"{{{key}}}" in content:
77-
content = content.replace(f"{{{key}}}", str(value))
78-
elif key == str(e).strip("'"):
79-
missing_keys.append(key)
73+
remaining_placeholders = set()
74+
75+
# Extract all placeholders
76+
placeholders = re.findall(r"(?<!\{)\{([^}\s]+)\}(?!\})", content)
77+
78+
for placeholder in placeholders:
79+
if placeholder in kwargs:
80+
content = content.replace(
81+
f"{{{placeholder}}}", str(kwargs[placeholder])
82+
)
83+
else:
84+
remaining_placeholders.add(placeholder)
85+
if placeholder == str(e).strip("'"):
86+
missing_keys.append(placeholder)
8087

8188
msg["content"] = content
8289

8390
if missing_keys:
8491
print(
85-
f"Warning: KeyError in message {i}. The following keys were not found in the content: {', '.join(missing_keys)}"
92+
f"Warning: KeyError in message {i}. The following keys were not found in the kwargs: {', '.join(missing_keys)}"
8693
)
8794

88-
# Check for any remaining placeholders
89-
import re
90-
91-
remaining_placeholders = re.findall(r"\{(.+?)\}", content)
9295
if remaining_placeholders:
9396
print(
9497
f"Warning: The following placeholders in message {i} were not replaced: {', '.join(remaining_placeholders)}"
@@ -135,13 +138,12 @@ def __new__(cls, base_path: Optional[str] = None):
135138
return cls._instance
136139

137140
def __init__(self, base_path: Optional[str] = None):
138-
if self._initialized:
139-
return
140-
self.base_path = base_path or "./prompts"
141-
self.prompt_names = get_prompt_file_names(self.base_path)
142-
self.prompts: Dict[str, PromptConfig] = {}
143-
self._initialized = True
144-
self.init()
141+
if not hasattr(self, "_initialized") or not self._initialized:
142+
self.base_path = base_path or "./prompts"
143+
self.prompt_names = get_prompt_file_names(self.base_path)
144+
self.prompts: Dict[str, PromptConfig] = {}
145+
self._initialized = True
146+
self.init()
145147

146148
def init(self):
147149
for prompt_name in self.prompt_names:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
setup(
1212
name="promptfile",
13-
version="0.3.3",
13+
version="0.4.0",
1414
packages=find_namespace_packages(),
1515
entry_points={},
1616
description="promptfile: language support for .prompt files",

0 commit comments

Comments
 (0)