I’ve been wrapping my head around this problem and can’t find a solution.
I have a pretty simple code:
import argparse
import json
def main():
parser = argparse.ArgumentParser(description="Process a JSON argument.")
parser.add_argument(
"--json",
type=str,
required=True,
help="JSON string or path to a JSON file."
)
args = parser.parse_args()
# Try to parse the argument as a JSON string or file path
try:
# First, attempt to parse it as a JSON string
data = json.loads(args.json)
print("Parsed JSON string successfully:", data)
except json.JSONDecodeError:
# If that fails, treat it as a file path
try:
with open(args.json, 'r') as file:
data = json.load(file)
print("Parsed JSON file successfully:", data)
except FileNotFoundError:
print("Error: Input is not a valid JSON string or file path.")
return
# Use the parsed dictionary (data)
print("JSON as dictionary:", data)
if __name__ == "__main__":
main()
saved as script.py
When I run it from Powershell with
python script.py --json '{"key": "value", "number": 42}'
I receive:
Traceback (most recent call last):
File "C:mypathscript.py", line 17, in main
data = json.loads(args.json)
File "C:Usersmyuserminiconda3envsti_nlplibjson__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "C:Usersmyuserminiconda3envsti_nlplibjsondecoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:Usersmyuserminiconda3envsti_nlplibjsondecoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:mypathscript.py", line 33, in <module>
main()
File "C:mypathscript.py", line 22, in main
with open(args.json, 'r') as file:
OSError: [Errno 22] Invalid argument: '{key: value, number: 42}'
When i run it with cmd (Anaconda prompt):
python script.py --json "{"key": "value", "number": 42}"
it works just fine:
Parsed JSON string successfully: {'key': 'value', 'number': 42}
JSON as dictionary: {'key': 'value', 'number': 42}
So… what is the issue with Powershell and how can I solve this problem?
3
Answers
Powershell handels differently than cmd – Ref
Or use like so
I use like this – put that json in a file and pass like so
The issue arises because PowerShell handles quotes differently from CMD or other shells. When you run the script in PowerShell, it interprets the single quotes (‘) in the JSON string literally instead of processing them correctly as part of the string. This causes a JSONDecodeError because JSON requires keys and string values to be enclosed in double quotes (").
You can try below approaches to resolve the issue. One: Use Escaped Double Quotes:
Or use single quote for entire argument like below:
This is an issue prior to the introduction of
PSNativeCommandArgumentPassing
, before that the double-quotes are consumed when passed as arguments. For comparison, you can change your Python script to:Then when called from PowerShell 7.2 and below you would see:
And in 7.3+ you will see that the
"
are preserved:That’s the cause of your issue. To solve this you will need to escape the
"
with. A way to handle this dynamically could be via
.Replace('"', '"')
:There are other alternatives too, for example encoding your Json to Base64 on PowerShell side and decoding it in Python, so in PowerShell:
And in Python:
Then you code should be compatible with all versions.