Add lzma.{encode,decode}_filter_properties().
diff --git a/Lib/lzma.py b/Lib/lzma.py
index 3786993..5adf51f 100644
--- a/Lib/lzma.py
+++ b/Lib/lzma.py
@@ -19,6 +19,7 @@
 
     "LZMACompressor", "LZMADecompressor", "LZMAFile", "LZMAError",
     "compress", "decompress", "check_is_supported",
+    "encode_filter_properties", "decode_filter_properties",
 ]
 
 import io
diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py
index ffde557..cc08bad 100644
--- a/Lib/test/test_lzma.py
+++ b/Lib/test/test_lzma.py
@@ -944,6 +944,49 @@
         # This value should not be a valid check ID.
         self.assertFalse(lzma.check_is_supported(lzma.CHECK_UNKNOWN))
 
+    def test_encode_filter_properties(self):
+        with self.assertRaises(TypeError):
+            lzma.encode_filter_properties(b"not a dict")
+        with self.assertRaises(ValueError):
+            lzma.encode_filter_properties({"id": 0x100})
+        with self.assertRaises(ValueError):
+            lzma.encode_filter_properties({"id": lzma.FILTER_LZMA2, "junk": 12})
+        with self.assertRaises(lzma.LZMAError):
+            lzma.encode_filter_properties({"id": lzma.FILTER_DELTA,
+                                           "dist": 9001})
+
+        # Test with parameters used by zipfile module.
+        props = lzma.encode_filter_properties({
+                "id": lzma.FILTER_LZMA1,
+                "pb": 2,
+                "lp": 0,
+                "lc": 3,
+                "dict_size": 8 << 20,
+            })
+        self.assertEqual(props, b"]\x00\x00\x80\x00")
+
+    def test_decode_filter_properties(self):
+        with self.assertRaises(TypeError):
+            lzma.decode_filter_properties(lzma.FILTER_X86, {"should be": bytes})
+        with self.assertRaises(lzma.LZMAError):
+            lzma.decode_filter_properties(lzma.FILTER_DELTA, b"too long")
+
+        # Test with parameters used by zipfile module.
+        filterspec = lzma.decode_filter_properties(
+                lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
+        self.assertEqual(filterspec["id"], lzma.FILTER_LZMA1)
+        self.assertEqual(filterspec["pb"], 2)
+        self.assertEqual(filterspec["lp"], 0)
+        self.assertEqual(filterspec["lc"], 3)
+        self.assertEqual(filterspec["dict_size"], 8 << 20)
+
+    def test_filter_properties_roundtrip(self):
+        spec1 = lzma.decode_filter_properties(
+                lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
+        reencoded = lzma.encode_filter_properties(spec1)
+        spec2 = lzma.decode_filter_properties(lzma.FILTER_LZMA1, reencoded)
+        self.assertEqual(spec1, spec2)
+
 
 # Test data: