diff --git a/Makefile b/Makefile
index bb740d577494ee381676c78d9189370e62222b0d..028641bbe393dcec83e7763f1b66bcc3e4ea2155 100644
--- a/Makefile
+++ b/Makefile
@@ -77,7 +77,7 @@ docs: docs/quickstart.html docs/manual.html
 
 build/pugixml-%: .FORCE | $(RELEASE)
 	@mkdir -p $(BUILD)
-	TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
+	TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python3 scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
 
 $(EXECUTABLE): $(OBJECTS)
 	$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
diff --git a/scripts/archive.py b/scripts/archive.py
index d102d05966f046cefe0287822c22bf27340244ac..e4fb7d46b53bb48d3f3007804b22c74a808dc3c2 100644
--- a/scripts/archive.py
+++ b/scripts/archive.py
@@ -1,18 +1,18 @@
+import io
 import os.path
 import sys
 import tarfile
 import time
 import zipfile
-import StringIO
 
 def read_file(path, use_crlf):
 	with open(path, 'rb') as file:
 		data = file.read()
 
-	if '\0' not in data:
-		data = data.replace('\r', '')
+	if b'\0' not in data:
+		data = data.replace(b'\r', b'')
 		if use_crlf:
-			data = data.replace('\n', '\r\n')
+			data = data.replace(b'\n', b'\r\n')
 
 	return data
 
@@ -24,7 +24,7 @@ def write_zip(target, arcprefix, timestamp, sources):
 			info = zipfile.ZipInfo(path)
 			info.date_time = time.localtime(timestamp)
 			info.compress_type = zipfile.ZIP_DEFLATED
-			info.external_attr = 0644 << 16L
+			info.external_attr = 0o644 << 16
 			archive.writestr(info, data)
 
 def write_tar(target, arcprefix, timestamp, sources, compression):
@@ -35,7 +35,7 @@ def write_tar(target, arcprefix, timestamp, sources, compression):
 			info = tarfile.TarInfo(path)
 			info.size = len(data)
 			info.mtime = timestamp
-			archive.addfile(info, StringIO.StringIO(data))
+			archive.addfile(info, io.BytesIO(data))
 
 if len(sys.argv) < 5:
 	raise RuntimeError('Usage: python archive.py <target> <archive prefix> <timestamp> <source files>')