55import subprocess
66import sys
77import locale
8+ import codecs
9+
10+ # Compatibility for subprocess.run (added in Python 3.5)
11+ def run_subprocess (cmd , timeout = None ):
12+ """Cross-platform subprocess runner for Python 2.7+ compatibility."""
13+ if hasattr (subprocess , 'run' ):
14+ # Python 3.5+
15+ return subprocess .run (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE , timeout = timeout )
16+ else :
17+ # Python 2.7, 3.3, 3.4
18+ popen = subprocess .Popen (cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
19+ stdout , stderr = popen .communicate ()
20+ # Create a simple result object similar to subprocess.CompletedProcess
21+ class Result :
22+ def __init__ (self , returncode , stdout , stderr ):
23+ self .returncode = returncode
24+ self .stdout = stdout
25+ self .stderr = stderr
26+ return Result (popen .returncode , stdout , stderr )
27+
28+ def safe_decode (data , encoding = 'utf-8' , errors = 'replace' ):
29+ """Safe decode for Python 2.7/3.x compatibility."""
30+ if isinstance (data , bytes ):
31+ try :
32+ return data .decode (encoding , errors )
33+ except UnicodeDecodeError :
34+ return data .decode (encoding , 'replace' )
35+ return data
836
937
1038def test_cli_output_flag_with_unicode ():
@@ -17,8 +45,9 @@ def test_cli_output_flag_with_unicode():
1745 source_code = 'print("❌ ✓ 🐍 Привет © ∀")'
1846
1947 # Create temporary source file
20- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.py' , delete = False , encoding = 'utf-8' ) as source_file :
21- source_file .write (source_code )
48+ # Python 2.7 doesn't support encoding parameter, so use binary mode
49+ with tempfile .NamedTemporaryFile (mode = 'wb' , suffix = '.py' , delete = False ) as source_file :
50+ source_file .write (source_code .encode ('utf-8' ))
2251 source_path = source_file .name
2352
2453 # Create temporary output file path
@@ -30,16 +59,17 @@ def test_cli_output_flag_with_unicode():
3059 os .unlink (output_path )
3160
3261 # Run pyminify CLI with --output flag (this should reproduce Windows encoding errors)
33- result = subprocess . run ([
62+ result = run_subprocess ([
3463 sys .executable , '-m' , 'python_minifier' ,
3564 source_path , '--output' , output_path
36- ], stdout = subprocess . PIPE , stderr = subprocess . PIPE , timeout = 30 )
65+ ], timeout = 30 )
3766
3867 # Test should fail if CLI command fails (indicates Windows encoding bug)
39- assert result .returncode == 0 , "CLI failed with encoding error: {}" .format (result .stderr )
68+ assert result .returncode == 0 , "CLI failed with encoding error: {}" .format (safe_decode ( result .stderr ) )
4069
4170 # Verify the output file was created and contains Unicode characters
42- with open (output_path , 'r' , encoding = 'utf-8' ) as f :
71+ # Python 2.7 doesn't support encoding parameter in open()
72+ with codecs .open (output_path , 'r' , encoding = 'utf-8' ) as f :
4373 minified_content = f .read ()
4474
4575 # Verify problematic Unicode characters are preserved
@@ -66,22 +96,24 @@ def test_cli_in_place_with_unicode():
6696 source_code = 'print("❌ ✓ 🐍 Привет © ∀")'
6797
6898 # Create temporary file
69- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.py' , delete = False , encoding = 'utf-8' ) as temp_file :
70- temp_file .write (source_code )
99+ # Python 2.7 doesn't support encoding parameter, so use binary mode
100+ with tempfile .NamedTemporaryFile (mode = 'wb' , suffix = '.py' , delete = False ) as temp_file :
101+ temp_file .write (source_code .encode ('utf-8' ))
71102 temp_path = temp_file .name
72103
73104 try :
74105 # Run pyminify with --in-place flag
75- result = subprocess . run ([
106+ result = run_subprocess ([
76107 sys .executable , '-m' , 'python_minifier' ,
77108 temp_path , '--in-place'
78- ], stdout = subprocess . PIPE , stderr = subprocess . PIPE , timeout = 30 )
109+ ], timeout = 30 )
79110
80111 # Test should fail if CLI command fails (indicates Windows encoding bug)
81- assert result .returncode == 0 , "CLI failed with encoding error: {}" .format (result .stderr )
112+ assert result .returncode == 0 , "CLI failed with encoding error: {}" .format (safe_decode ( result .stderr ) )
82113
83114 # Verify Unicode characters are preserved in the modified file
84- with open (temp_path , 'r' , encoding = 'utf-8' ) as f :
115+ # Python 2.7 doesn't support encoding parameter in open()
116+ with codecs .open (temp_path , 'r' , encoding = 'utf-8' ) as f :
85117 content = f .read ()
86118
87119 assert "✓" in content
@@ -103,22 +135,23 @@ def test_cli_stdout_with_unicode():
103135 """
104136 source_code = 'print("❌ ✓ 🐍 Привет © ∀")'
105137
106- with tempfile .NamedTemporaryFile (mode = 'w' , suffix = '.py' , delete = False , encoding = 'utf-8' ) as temp_file :
107- temp_file .write (source_code )
138+ # Python 2.7 doesn't support encoding parameter, so use binary mode
139+ with tempfile .NamedTemporaryFile (mode = 'wb' , suffix = '.py' , delete = False ) as temp_file :
140+ temp_file .write (source_code .encode ('utf-8' ))
108141 temp_path = temp_file .name
109142
110143 try :
111144 # Run without --output or --in-place (should output to stdout)
112- # Use stdout=PIPE, stderr=PIPE to avoid subprocess decoding issues with Windows
145+ # Use our compatibility function to avoid subprocess decoding issues with Windows
113146 # We'll manually decode as UTF-8 to properly handle Unicode characters
114- result = subprocess . run ([
147+ result = run_subprocess ([
115148 sys .executable , '-m' , 'python_minifier' , temp_path
116- ], stdout = subprocess . PIPE , stderr = subprocess . PIPE , timeout = 30 )
149+ ], timeout = 30 )
117150
118- assert result .returncode == 0 , "Stdout output failed: {}" .format (result .stderr . decode ( 'utf-8' , errors = 'replace' ))
151+ assert result .returncode == 0 , "Stdout output failed: {}" .format (safe_decode ( result .stderr ))
119152
120153 # Decode stdout and verify Unicode characters are present
121- stdout_text = result .stdout . decode ( 'utf-8' , errors = 'replace' )
154+ stdout_text = safe_decode ( result .stdout )
122155 assert "❌" in stdout_text
123156 assert "✓" in stdout_text
124157 assert "🐍" in stdout_text
0 commit comments