| Offset 1, 121 lines modified | Offset 0, 0 lines modified | ||
| 1 | Key·0x42726577: | ||
| 2 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 3 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 4 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 5 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 6 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 7 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 8 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 9 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 10 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 11 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 12 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 13 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 14 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 15 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 16 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 17 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 18 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 19 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 20 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 21 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 22 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 23 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 24 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 25 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 26 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 27 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 28 | 0000000000000000000000000000000000000000000000000000000000000000000000 | ||
| 29 | 000000000000000000000000000000000000000000 | ||
| 30 | Key·0x7109871a: | ||
| 31 | f7050000f3050000b50300002c000000280000000301000020000000ab5cf407e1f984 | ||
| 32 | c91279de36988e111dbc3655e7f62eb6f009c344f674c980496d030000690300003082 | ||
| 33 | 03653082024da003020102020863707fe532bb2ae7300d06092a864886f70d01010b05 | ||
| 34 | 003060310b300906035504061302554b310c300a060355040813034f5247310c300a06 | ||
| 35 | 0355040713034f524731133011060355040a130a6664726f69642e6f7267310f300d06 | ||
| 36 | 0355040b13064644726f6964310f300d060355040313064644726f69643020170d3236 | ||
| 37 | 303632373135343331325a180f32303533313131323135343331325a3060310b300906 | ||
| 38 | 035504061302554b310c300a060355040813034f5247310c300a060355040713034f52 | ||
| 39 | 4731133011060355040a130a6664726f69642e6f7267310f300d060355040b13064644 | ||
| 40 | 726f6964310f300d060355040313064644726f696430820122300d06092a864886f70d | ||
| 41 | 01010105000382010f003082010a0282010100ac74a8f4fb5ff9c1a0338278598eb9c6 | ||
| 42 | ba0fce0774e5f2dfe7d8aff70c0cb2535a834e125f1581127f7a6f5d3f86dc5195fd7a | ||
| 43 | 4b1c92b26bd6422d7d34de63f255b1782446868cb7bfdc3b992ccb233a52ef9c4d5f81 | ||
| 44 | 954926ca92954b14f8046ec50a095dd5556832565712fd9d41cd934410056864573af7 | ||
| 45 | d8187d1774c6a004b928eb712a907ec5944e75acd901cfb09a1ce230815caae69da3a0 | ||
| 46 | b6bf6fb6d63156b21b8922ed1917331c4f1421eaa8dbb232f7832dcc35e7a6e6907f62 | ||
| 47 | df44fe4a73cd3f238002dfc7a5e2e2fc64ce1596966c7c411f63ad2e19c0339354c530 | ||
| 48 | 83b31e8cfb923799d505bbaa8c2d6bf92187fe3ae13fe30eabe346242d110203010001 | ||
| 49 | a321301f301d0603551d0e04160414ecb0d0226aa2fe884f4897c348146f3ffffc96b7 | ||
| 50 | 300d06092a864886f70d01010b0500038201010048373d1fdd119f7858e6e3c2e5c181 | ||
| 51 | b3ed8072b53c4ab90889efb9b8cd0c23eab3e01752c48305ee01f073d5a108e62196d4 | ||
| 52 | ce553bb0022a0055cac40979bccc03c1a6c90ee4baaad9f217f746731470b128bfd3b2 | ||
| 53 | 4d67879509be45a91d5042396036d3b05594d1f5055dca470801751296b3c5f4d72ece | ||
| 54 | c04320cbbb69ee8a6d9d39309916850db9939afdfca7c90755c57a88fe82343d2b02cb | ||
| 55 | fa45c1467ddc6e81e59fadd39925d9b2e62e85c55625247f04ce42a115ae52a52dec25 | ||
| 56 | f249cf08a392f7efb473a319ea4e410e74bb516475b7c881610fb95a013a9209c4243c | ||
| 57 | 948166bff03e2a50f4c1e6da3bad7c6a918afeeb7472bc45ad09efe63b47200c000000 | ||
| 58 | 080000000df0efbe03000000000000000c01000008010000030100000001000089adb9 | ||
| 59 | cc0dcf3f7de614af2616c6cee74e81b03b08db047b4e6b3fd92b3aa4b043a06f4a41e1 | ||
| 60 | b423af8d14bb5a129043a03610f63ce260d263253e18b6bde4c22c1fc6960f6ab4c4e3 | ||
| 61 | eb361faaac99693c2ac7ea2cb15ee04726b03a76583265fc040d7add903e891627bdf8 | ||
| 62 | b5e7b1e1adb25a57943c1e45efe1badacb422df549fe8cf0affb5c873dea6848bd70e0 | ||
| 63 | 0cc8136f29300109c141e6e8675ddd4c1dd19fa85ecb043814b3fbdd956de4c46bcbe0 | ||
| 64 | 7f3ca8ba08160bc252908d6624f4a942a04445c3957bd91f29ab89b568b25c06ff6e7a | ||
| 65 | 3edad085f2a8ad6ac5717ae3768c9d4ce0f2645c70a049b09bf5aaffe38ee7bea8a4fa | ||
| 66 | f967c564491d236b2601000030820122300d06092a864886f70d01010105000382010f | ||
| 67 | 003082010a0282010100ac74a8f4fb5ff9c1a0338278598eb9c6ba0fce0774e5f2dfe7 | ||
| 68 | d8aff70c0cb2535a834e125f1581127f7a6f5d3f86dc5195fd7a4b1c92b26bd6422d7d | ||
| 69 | 34de63f255b1782446868cb7bfdc3b992ccb233a52ef9c4d5f81954926ca92954b14f8 | ||
| 70 | 046ec50a095dd5556832565712fd9d41cd934410056864573af7d8187d1774c6a004b9 | ||
| 71 | 28eb712a907ec5944e75acd901cfb09a1ce230815caae69da3a0b6bf6fb6d63156b21b | ||
| 72 | 8922ed1917331c4f1421eaa8dbb232f7832dcc35e7a6e6907f62df44fe4a73cd3f2380 | ||
| 73 | 02dfc7a5e2e2fc64ce1596966c7c411f63ad2e19c0339354c53083b31e8cfb923799d5 | ||
| 74 | 05bbaa8c2d6bf92187fe3ae13fe30eabe346242d110203010001 | ||
| 75 | Key·0xf05368c0: | ||
| 76 | f7050000f3050000ad0300002c000000280000000301000020000000ab5cf407e1f984 | ||
| 77 | c91279de36988e111dbc3655e7f62eb6f009c344f674c980496d030000690300003082 | ||
| 78 | 03653082024da003020102020863707fe532bb2ae7300d06092a864886f70d01010b05 | ||
| 79 | 003060310b300906035504061302554b310c300a060355040813034f5247310c300a06 | ||
| 80 | 0355040713034f524731133011060355040a130a6664726f69642e6f7267310f300d06 | ||
| 81 | 0355040b13064644726f6964310f300d060355040313064644726f69643020170d3236 | ||
| 82 | 303632373135343331325a180f32303533313131323135343331325a3060310b300906 | ||
| 83 | 035504061302554b310c300a060355040813034f5247310c300a060355040713034f52 | ||
| 84 | 4731133011060355040a130a6664726f69642e6f7267310f300d060355040b13064644 | ||
| 85 | 726f6964310f300d060355040313064644726f696430820122300d06092a864886f70d | ||
| 86 | 01010105000382010f003082010a0282010100ac74a8f4fb5ff9c1a0338278598eb9c6 | ||
| 87 | ba0fce0774e5f2dfe7d8aff70c0cb2535a834e125f1581127f7a6f5d3f86dc5195fd7a | ||
| 88 | 4b1c92b26bd6422d7d34de63f255b1782446868cb7bfdc3b992ccb233a52ef9c4d5f81 | ||
| 89 | 954926ca92954b14f8046ec50a095dd5556832565712fd9d41cd934410056864573af7 | ||
| 90 | d8187d1774c6a004b928eb712a907ec5944e75acd901cfb09a1ce230815caae69da3a0 | ||
| 91 | b6bf6fb6d63156b21b8922ed1917331c4f1421eaa8dbb232f7832dcc35e7a6e6907f62 | ||
| 92 | df44fe4a73cd3f238002dfc7a5e2e2fc64ce1596966c7c411f63ad2e19c0339354c530 | ||
| 93 | 83b31e8cfb923799d505bbaa8c2d6bf92187fe3ae13fe30eabe346242d110203010001 | ||
| 94 | a321301f301d0603551d0e04160414ecb0d0226aa2fe884f4897c348146f3ffffc96b7 | ||
| 95 | 300d06092a864886f70d01010b0500038201010048373d1fdd119f7858e6e3c2e5c181 | ||
| 96 | b3ed8072b53c4ab90889efb9b8cd0c23eab3e01752c48305ee01f073d5a108e62196d4 | ||
| 97 | ce553bb0022a0055cac40979bccc03c1a6c90ee4baaad9f217f746731470b128bfd3b2 | ||
| 98 | 4d67879509be45a91d5042396036d3b05594d1f5055dca470801751296b3c5f4d72ece | ||
| 99 | c04320cbbb69ee8a6d9d39309916850db9939afdfca7c90755c57a88fe82343d2b02cb | ||
| 100 | fa45c1467ddc6e81e59fadd39925d9b2e62e85c55625247f04ce42a115ae52a52dec25 | ||
| 101 | f249cf08a392f7efb473a319ea4e410e74bb516475b7c881610fb95a013a9209c4243c | ||
| 102 | 948166bff03e2a50f4c1e6da3bad7c6a918afeeb7472bc45ad09efe63b472018000000 | ||
| 103 | ffffff7f0000000018000000ffffff7f0c01000008010000030100000001000025c450 | ||
| 104 | b32b2d4b6a2d8bb474d4f33eb37d55d94cdcebda84f784d2716c49695858820fddafc8 | ||
| 105 | 541051e222cfdd6b0be6e51da8d21f32a4e811551a6a42cdf9876b279b4fef715a1877 | ||
| 106 | c23e10562cf990291d5f1a2e5ae13d3b0c1b68f09330ecea6c3327e9b4f932b9461ef3 | ||
| 107 | 45c4070a8fbb172d215468a1dcb84571a0094c7bbba358e5ccc96aae94fcc236d43bd7 | ||
| 108 | dbfd648114b19a8a3006a8349c08079bf663ca4f14f92d6f90f44f3beaf3fd5471a887 | ||
| 109 | b385c328a74cdcd21ddf00731b39bfa82d84ab735dfbbfa8997f5b93044c9dba930a03 | ||
| 110 | 810953b9569fe00cfac566851affa92d2a219193478566dd4f4e06af2eb3cff090726d | ||
| 111 | fb4c92b9ea456b1e2601000030820122300d06092a864886f70d01010105000382010f | ||
| 112 | 003082010a0282010100ac74a8f4fb5ff9c1a0338278598eb9c6ba0fce0774e5f2dfe7 | ||
| 113 | d8aff70c0cb2535a834e125f1581127f7a6f5d3f86dc5195fd7a4b1c92b26bd6422d7d | ||
| 114 | 34de63f255b1782446868cb7bfdc3b992ccb233a52ef9c4d5f81954926ca92954b14f8 | ||
| 115 | 046ec50a095dd5556832565712fd9d41cd934410056864573af7d8187d1774c6a004b9 | ||
| 116 | 28eb712a907ec5944e75acd901cfb09a1ce230815caae69da3a0b6bf6fb6d63156b21b | ||
| 117 | 8922ed1917331c4f1421eaa8dbb232f7832dcc35e7a6e6907f62df44fe4a73cd3f2380 | ||
| 118 | 02dfc7a5e2e2fc64ce1596966c7c411f63ad2e19c0339354c53083b31e8cfb923799d5 | ||
| 119 | 05bbaa8c2d6bf92187fe3ae13fe30eabe346242d110203010001 | ||
| Offset 1, 8 lines modified | Offset 1, 8 lines modified | ||
| 1 | Zip·file·size:·633 | 1 | Zip·file·size:·63356881·bytes,·number·of·entries:·215 |
| 2 | -rw-r--r--··0.0·unx·······56·b-·defN·81-Jan-01·01:01·META-INF/com/android/build/gradle/app-metadata.properties | 2 | -rw-r--r--··0.0·unx·······56·b-·defN·81-Jan-01·01:01·META-INF/com/android/build/gradle/app-metadata.properties |
| 3 | -rw-r--r--··0.0·unx······120·b-·defN·81-Jan-01·01:01·META-INF/version-control-info.textproto | 3 | -rw-r--r--··0.0·unx······120·b-·defN·81-Jan-01·01:01·META-INF/version-control-info.textproto |
| 4 | -rw-r--r--··0.0·unx·····6990·b-·stor·81-Jan-01·01:01·assets/dexopt/baseline.prof | 4 | -rw-r--r--··0.0·unx·····6990·b-·stor·81-Jan-01·01:01·assets/dexopt/baseline.prof |
| 5 | -rw-r--r--··0.0·unx······392·b-·stor·81-Jan-01·01:01·assets/dexopt/baseline.profm | 5 | -rw-r--r--··0.0·unx······392·b-·stor·81-Jan-01·01:01·assets/dexopt/baseline.profm |
| 6 | -rw-r--r--··0.0·unx·13583992·b-·defN·81-Jan-01·01:01·classes.dex | 6 | -rw-r--r--··0.0·unx·13583992·b-·defN·81-Jan-01·01:01·classes.dex |
| 7 | -rw-r--r--··0.0·unx··4070048·b-·defN·81-Jan-01·01:01·classes2.dex | 7 | -rw-r--r--··0.0·unx··4070048·b-·defN·81-Jan-01·01:01·classes2.dex |
| 8 | -rw-r--r--··0.0·unx····10096·b-·stor·81-Jan-01·01:01·lib/arm64-v8a/libandroidx.graphics.path.so | 8 | -rw-r--r--··0.0·unx····10096·b-·stor·81-Jan-01·01:01·lib/arm64-v8a/libandroidx.graphics.path.so |
| Offset 70, 15 lines modified | Offset 70, 15 lines modified | ||
| 70 | -rw-r--r--··0.0·unx····24336·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap-native/x86_64/mmap.so | 70 | -rw-r--r--··0.0·unx····24336·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap-native/x86_64/mmap.so |
| 71 | -rw-r--r--··0.0·unx····37608·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap-native/x86_64/zlib.so | 71 | -rw-r--r--··0.0·unx····37608·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap-native/x86_64/zlib.so |
| 72 | -rw-r--r--··0.0·unx···624933·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap.imy | 72 | -rw-r--r--··0.0·unx···624933·b-·stor·81-Jan-01·01:01·assets/chaquopy/bootstrap.imy |
| 73 | -rw-r--r--··0.0·unx·····4242·b-·defN·81-Jan-01·01:01·assets/chaquopy/build.json | 73 | -rw-r--r--··0.0·unx·····4242·b-·defN·81-Jan-01·01:01·assets/chaquopy/build.json |
| 74 | -rw-r--r--··0.0·unx···299427·b-·defN·81-Jan-01·01:01·assets/chaquopy/cacert.pem | 74 | -rw-r--r--··0.0·unx···299427·b-·defN·81-Jan-01·01:01·assets/chaquopy/cacert.pem |
| 75 | -rw-r--r--··0.0·unx··2594339·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-arm64-v8a.imy | 75 | -rw-r--r--··0.0·unx··2594339·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-arm64-v8a.imy |
| 76 | -rw-r--r--··0.0·unx··2315511·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-armeabi-v7a.imy | 76 | -rw-r--r--··0.0·unx··2315511·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-armeabi-v7a.imy |
| 77 | -rw-r--r--··0.0·unx··373 | 77 | -rw-r--r--··0.0·unx··3739796·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-common.imy |
| 78 | -rw-r--r--··0.0·unx··2725620·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-x86_64.imy | 78 | -rw-r--r--··0.0·unx··2725620·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-x86_64.imy |
| 79 | -rw-r--r--··0.0·unx··1478595·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-arm64-v8a.imy | 79 | -rw-r--r--··0.0·unx··1478595·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-arm64-v8a.imy |
| 80 | -rw-r--r--··0.0·unx··1386480·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-armeabi-v7a.imy | 80 | -rw-r--r--··0.0·unx··1386480·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-armeabi-v7a.imy |
| 81 | -rw-r--r--··0.0·unx··4812526·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-common.imy | 81 | -rw-r--r--··0.0·unx··4812526·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-common.imy |
| 82 | -rw-r--r--··0.0·unx··1508233·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-x86_64.imy | 82 | -rw-r--r--··0.0·unx··1508233·b-·stor·81-Jan-01·01:01·assets/chaquopy/stdlib-x86_64.imy |
| 83 | -rw----·····2.4·fat·····1738·b-·defN·81-Jan-01·01:01·DebugProbesKt.bin | 83 | -rw----·····2.4·fat·····1738·b-·defN·81-Jan-01·01:01·DebugProbesKt.bin |
| 84 | -rw----·····2.4·fat········6·b-·stor·81-Jan-01·01:01·META-INF/androidx.activity_activity-compose.version | 84 | -rw----·····2.4·fat········6·b-·stor·81-Jan-01·01:01·META-INF/androidx.activity_activity-compose.version |
| Offset 210, 11 lines modified | Offset 210, 8 lines modified | ||
| 210 | -rw----·····0.0·fat······225·b-·stor·81-Jan-01·01:01·res/wN.9.png | 210 | -rw----·····0.0·fat······225·b-·stor·81-Jan-01·01:01·res/wN.9.png |
| 211 | -rw----·····0.0·fat·····2456·b-·defN·81-Jan-01·01:01·res/xN.xml | 211 | -rw----·····0.0·fat·····2456·b-·defN·81-Jan-01·01:01·res/xN.xml |
| 212 | -rw----·····0.0·fat······221·b-·stor·81-Jan-01·01:01·res/xa.9.png | 212 | -rw----·····0.0·fat······221·b-·stor·81-Jan-01·01:01·res/xa.9.png |
| 213 | -rw----·····0.0·fat······221·b-·stor·81-Jan-01·01:01·res/z-.9.png | 213 | -rw----·····0.0·fat······221·b-·stor·81-Jan-01·01:01·res/z-.9.png |
| 214 | -rw----·····0.0·fat······206·b-·stor·81-Jan-01·01:01·res/zL.png | 214 | -rw----·····0.0·fat······206·b-·stor·81-Jan-01·01:01·res/zL.png |
| 215 | -rw----·····0.0·fat······884·b-·stor·81-Jan-01·01:01·res/zz.png | 215 | -rw----·····0.0·fat······884·b-·stor·81-Jan-01·01:01·res/zz.png |
| 216 | -rw----·····0.0·fat···415976·b-·stor·81-Jan-01·01:01·resources.arsc | 216 | -rw----·····0.0·fat···415976·b-·stor·81-Jan-01·01:01·resources.arsc |
| 217 | -rw----·····2.0·fat····22646·b-·defN·81-Jan-01·01:01·META-INF/57818ACA.SF | ||
| 218 | -rw----·····2.0·fat·····1344·b-·defN·81-Jan-01·01:01·META-INF/57818ACA.RSA | ||
| 219 | -rw----·····2.0·fat····22519·b-·defN·81-Jan-01·01:01·META-INF/MANIFEST.MF | ||
| 220 | 21 | 217 | 215·files,·74712953·bytes·uncompressed,·62832225·bytes·compressed:··15.9% |
| Offset 1, 8 lines modified | Offset 1, 8 lines modified | ||
| 1 | Zip·file·size:·373 | 1 | Zip·file·size:·3739796·bytes,·number·of·entries:·773 |
| 2 | -rw----·····2.0·fat····34703·b-·defN·80-Feb-01·00:00·six.py | 2 | -rw----·····2.0·fat····34703·b-·defN·80-Feb-01·00:00·six.py |
| 3 | -rw----·····2.0·fat···165012·b-·defN·80-Feb-01·00:00·typing_extensions.py | 3 | -rw----·····2.0·fat···165012·b-·defN·80-Feb-01·00:00·typing_extensions.py |
| 4 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·PIL/ | 4 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·PIL/ |
| 5 | -rw----·····2.0·fat·····3477·b-·defN·80-Feb-01·00:00·PIL/BdfFontFile.py | 5 | -rw----·····2.0·fat·····3477·b-·defN·80-Feb-01·00:00·PIL/BdfFontFile.py |
| 6 | -rw----·····2.0·fat····16584·b-·defN·80-Feb-01·00:00·PIL/BlpImagePlugin.py | 6 | -rw----·····2.0·fat····16584·b-·defN·80-Feb-01·00:00·PIL/BlpImagePlugin.py |
| 7 | -rw----·····2.0·fat····19758·b-·defN·80-Feb-01·00:00·PIL/BmpImagePlugin.py | 7 | -rw----·····2.0·fat····19758·b-·defN·80-Feb-01·00:00·PIL/BmpImagePlugin.py |
| 8 | -rw----·····2.0·fat·····1753·b-·defN·80-Feb-01·00:00·PIL/BufrStubImagePlugin.py | 8 | -rw----·····2.0·fat·····1753·b-·defN·80-Feb-01·00:00·PIL/BufrStubImagePlugin.py |
| Offset 276, 42 lines modified | Offset 276, 42 lines modified | ||
| 276 | -rw----·····2.0·fat·····5364·b-·defN·80-Feb-01·00:00·defusedxml/xmlrpc.py | 276 | -rw----·····2.0·fat·····5364·b-·defN·80-Feb-01·00:00·defusedxml/xmlrpc.py |
| 277 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/ | 277 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/ |
| 278 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/INSTALLER | 278 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/INSTALLER |
| 279 | -rw----·····2.0·fat·····2409·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/LICENSE | 279 | -rw----·····2.0·fat·····2409·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/LICENSE |
| 280 | -rw----·····2.0·fat····32518·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/METADATA | 280 | -rw----·····2.0·fat····32518·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/METADATA |
| 281 | -rw----·····2.0·fat·······11·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/top_level.txt | 281 | -rw----·····2.0·fat·······11·b-·defN·80-Feb-01·00:00·defusedxml-0.7.1.dist-info/top_level.txt |
| 282 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/ | 282 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/ |
| 283 | -rw----·····2.0·fat·····3 | 283 | -rw----·····2.0·fat·····3469·b-·defN·80-Feb-01·00:00·filelock/__init__.py |
| 284 | -rw----·····2.0·fat····8 | 284 | -rw----·····2.0·fat····82263·b-·defN·80-Feb-01·00:00·filelock/_api.py |
| 285 | -rw----·····2.0·fat····· | 285 | -rw----·····2.0·fat·····6111·b-·defN·80-Feb-01·00:00·filelock/_async.py |
| 286 | -rw----·····2.0·fat····13 | 286 | -rw----·····2.0·fat····13325·b-·defN·80-Feb-01·00:00·filelock/_async_read_write.py |
| 287 | -rw----·····2.0·fat·····2981·b-·defN·80-Feb-01·00:00·filelock/_descriptor.py | 287 | -rw----·····2.0·fat·····2981·b-·defN·80-Feb-01·00:00·filelock/_descriptor.py |
| 288 | -rw----·····2.0·fat·····2 | 288 | -rw----·····2.0·fat·····2699·b-·defN·80-Feb-01·00:00·filelock/_error.py |
| 289 | -rw----·····2.0·fat·····8 | 289 | -rw----·····2.0·fat·····8415·b-·defN·80-Feb-01·00:00·filelock/_identity.py |
| 290 | -rw----·····2.0·fat····1 | 290 | -rw----·····2.0·fat····15152·b-·defN·80-Feb-01·00:00·filelock/_lease.py |
| 291 | -rw----·····2.0·fat·····6026·b-·defN·80-Feb-01·00:00·filelock/_marker.py | 291 | -rw----·····2.0·fat·····6026·b-·defN·80-Feb-01·00:00·filelock/_marker.py |
| 292 | -rw----·····2.0·fat····32 | 292 | -rw----·····2.0·fat····32895·b-·defN·80-Feb-01·00:00·filelock/_read_write.py |
| 293 | -rw----·····2.0·fat····1 | 293 | -rw----·····2.0·fat····13014·b-·defN·80-Feb-01·00:00·filelock/_soft.py |
| 294 | -rw----·····2.0·fat······187·b-·defN·80-Feb-01·00:00·filelock/_soft_protocol.py | 294 | -rw----·····2.0·fat······187·b-·defN·80-Feb-01·00:00·filelock/_soft_protocol.py |
| 295 | -rw----·····2.0·fat····3 | 295 | -rw----·····2.0·fat····38823·b-·defN·80-Feb-01·00:00·filelock/_strict.py |
| 296 | -rw----·····2.0·fat·····8722·b-·defN·80-Feb-01·00:00·filelock/_unix.py | 296 | -rw----·····2.0·fat·····8722·b-·defN·80-Feb-01·00:00·filelock/_unix.py |
| 297 | -rw----·····2.0·fat·····63 | 297 | -rw----·····2.0·fat·····6356·b-·defN·80-Feb-01·00:00·filelock/_util.py |
| 298 | -rw----·····2.0·fat····15 | 298 | -rw----·····2.0·fat····15988·b-·defN·80-Feb-01·00:00·filelock/_windows.py |
| 299 | -rw----·····2.0·fat····34 | 299 | -rw----·····2.0·fat····34599·b-·defN·80-Feb-01·00:00·filelock/asyncio.py |
| 300 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/py.typed | 300 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/py.typed |
| 301 | -rw----·····2.0·fat······522·b-·defN·80-Feb-01·00:00·filelock/version.py | 301 | -rw----·····2.0·fat······522·b-·defN·80-Feb-01·00:00·filelock/version.py |
| 302 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/ | 302 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/ |
| 303 | -rw----·····2.0·fat······370·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/__init__.py | 303 | -rw----·····2.0·fat······370·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/__init__.py |
| 304 | -rw----·····2.0·fat···· | 304 | -rw----·····2.0·fat····11492·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/_async.py |
| 305 | -rw----·····2.0·fat····4 | 305 | -rw----·····2.0·fat····43201·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/_sync.py |
| 306 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock-3.3 | 306 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/ |
| 307 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·filelock-3.3 | 307 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/INSTALLER |
| 308 | -rw----·····2.0·fat····· | 308 | -rw----·····2.0·fat·····2028·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/METADATA |
| 309 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock-3.3 | 309 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/licenses/ |
| 310 | -rw----·····2.0·fat·····1088·b-·defN·80-Feb-01·00:00·filelock-3.3 | 310 | -rw----·····2.0·fat·····1088·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/licenses/LICENSE |
| 311 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·html2text/ | 311 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·html2text/ |
| 312 | -rw----·····2.0·fat····37885·b-·defN·80-Feb-01·00:00·html2text/__init__.py | 312 | -rw----·····2.0·fat····37885·b-·defN·80-Feb-01·00:00·html2text/__init__.py |
| 313 | -rw----·····2.0·fat·······30·b-·defN·80-Feb-01·00:00·html2text/__main__.py | 313 | -rw----·····2.0·fat·······30·b-·defN·80-Feb-01·00:00·html2text/__main__.py |
| 314 | -rw----·····2.0·fat·······63·b-·defN·80-Feb-01·00:00·html2text/_typing.py | 314 | -rw----·····2.0·fat·······63·b-·defN·80-Feb-01·00:00·html2text/_typing.py |
| 315 | -rw----·····2.0·fat······519·b-·defN·80-Feb-01·00:00·html2text/_version.py | 315 | -rw----·····2.0·fat······519·b-·defN·80-Feb-01·00:00·html2text/_version.py |
| 316 | -rw----·····2.0·fat····10300·b-·defN·80-Feb-01·00:00·html2text/cli.py | 316 | -rw----·····2.0·fat····10300·b-·defN·80-Feb-01·00:00·html2text/cli.py |
| 317 | -rw----·····2.0·fat·····4052·b-·defN·80-Feb-01·00:00·html2text/config.py | 317 | -rw----·····2.0·fat·····4052·b-·defN·80-Feb-01·00:00·html2text/config.py |
| Offset 687, 36 lines modified | Offset 687, 36 lines modified | ||
| 687 | -rw----·····2.0·fat·····1066·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/LICENSE | 687 | -rw----·····2.0·fat·····1066·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/LICENSE |
| 688 | -rw----·····2.0·fat·····1658·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/METADATA | 688 | -rw----·····2.0·fat·····1658·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/METADATA |
| 689 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/top_level.txt | 689 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/top_level.txt |
| 690 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve/ | 690 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve/ |
| 691 | -rw----·····2.0·fat·····4581·b-·defN·80-Feb-01·00:00·soupsieve/__init__.py | 691 | -rw----·····2.0·fat·····4581·b-·defN·80-Feb-01·00:00·soupsieve/__init__.py |
| 692 | -rw----·····2.0·fat·····6766·b-·defN·80-Feb-01·00:00·soupsieve/__meta__.py | 692 | -rw----·····2.0·fat·····6766·b-·defN·80-Feb-01·00:00·soupsieve/__meta__.py |
| 693 | -rw----·····2.0·fat····60276·b-·defN·80-Feb-01·00:00·soupsieve/css_match.py | 693 | -rw----·····2.0·fat····60276·b-·defN·80-Feb-01·00:00·soupsieve/css_match.py |
| 694 | -rw----·····2.0·fat····481 | 694 | -rw----·····2.0·fat····48182·b-·defN·80-Feb-01·00:00·soupsieve/css_parser.py |
| 695 | -rw----·····2.0·fat····10014·b-·defN·80-Feb-01·00:00·soupsieve/css_types.py | 695 | -rw----·····2.0·fat····10014·b-·defN·80-Feb-01·00:00·soupsieve/css_types.py |
| 696 | -rw----·····2.0·fat·····4362·b-·defN·80-Feb-01·00:00·soupsieve/pretty.py | 696 | -rw----·····2.0·fat·····4362·b-·defN·80-Feb-01·00:00·soupsieve/pretty.py |
| 697 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve/py.typed | 697 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve/py.typed |
| 698 | -rw----·····2.0·fat·····3352·b-·defN·80-Feb-01·00:00·soupsieve/util.py | 698 | -rw----·····2.0·fat·····3352·b-·defN·80-Feb-01·00:00·soupsieve/util.py |
| 699 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve-2.9.dist-info/ | 699 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/ |
| 700 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·soupsieve-2.9.dist-info/INSTALLER | 700 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/INSTALLER |
| 701 | -rw----·····2.0·fat·····458 | 701 | -rw----·····2.0·fat·····4586·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/METADATA |
| 702 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve-2.9.dist-info/licenses/ | 702 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/licenses/ |
| 703 | -rw----·····2.0·fat·····1096·b-·defN·80-Feb-01·00:00·soupsieve-2.9.dist-info/licenses/LICENSE.md | 703 | -rw----·····2.0·fat·····1096·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/licenses/LICENSE.md |
| 704 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib/ | 704 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib/ |
| 705 | -rw----·····2.0·fat·····5529·b-·defN·80-Feb-01·00:00·svglib/__init__.py | 705 | -rw----·····2.0·fat·····5529·b-·defN·80-Feb-01·00:00·svglib/__init__.py |
| 706 | -rw----·····2.0·fat····21818·b-·defN·80-Feb-01·00:00·svglib/fonts.py | 706 | -rw----·····2.0·fat····21818·b-·defN·80-Feb-01·00:00·svglib/fonts.py |
| 707 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib/py.typed | 707 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib/py.typed |
| 708 | -rw----·····2.0·fat··· | 708 | -rw----·····2.0·fat···111685·b-·defN·80-Feb-01·00:00·svglib/svglib.py |
| 709 | -rw----·····2.0·fat····19295·b-·defN·80-Feb-01·00:00·svglib/utils.py | 709 | -rw----·····2.0·fat····19295·b-·defN·80-Feb-01·00:00·svglib/utils.py |
| 710 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib-2. | 710 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/ |
| 711 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·svglib-2. | 711 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/INSTALLER |
| 712 | -rw----·····2.0·fat····1 | 712 | -rw----·····2.0·fat····14081·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/METADATA |
| 713 | -rw----·····2.0·fat·······40·b-·defN·80-Feb-01·00:00·svglib-2. | 713 | -rw----·····2.0·fat·······40·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/entry_points.txt |
| 714 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib-2. | 714 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/licenses/ |
| 715 | -rw----·····2.0·fat·····7637·b-·defN·80-Feb-01·00:00·svglib-2. | 715 | -rw----·····2.0·fat·····7637·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/licenses/LICENSE.txt |
| 716 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·tinycss/ | 716 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·tinycss/ |
| 717 | -rw----·····2.0·fat·····1214·b-·defN·80-Feb-01·00:00·tinycss/__init__.py | 717 | -rw----·····2.0·fat·····1214·b-·defN·80-Feb-01·00:00·tinycss/__init__.py |
| 718 | -rw----·····2.0·fat····12290·b-·defN·80-Feb-01·00:00·tinycss/color3.py | 718 | -rw----·····2.0·fat····12290·b-·defN·80-Feb-01·00:00·tinycss/color3.py |
| 719 | -rw----·····2.0·fat····29078·b-·defN·80-Feb-01·00:00·tinycss/css21.py | 719 | -rw----·····2.0·fat····29078·b-·defN·80-Feb-01·00:00·tinycss/css21.py |
| 720 | -rw----·····2.0·fat·····9174·b-·defN·80-Feb-01·00:00·tinycss/decoding.py | 720 | -rw----·····2.0·fat·····9174·b-·defN·80-Feb-01·00:00·tinycss/decoding.py |
| 721 | -rw----·····2.0·fat·····5767·b-·defN·80-Feb-01·00:00·tinycss/fonts3.py | 721 | -rw----·····2.0·fat·····5767·b-·defN·80-Feb-01·00:00·tinycss/fonts3.py |
| 722 | -rw----·····2.0·fat·····5118·b-·defN·80-Feb-01·00:00·tinycss/page3.py | 722 | -rw----·····2.0·fat·····5118·b-·defN·80-Feb-01·00:00·tinycss/page3.py |
| Offset 768, 8 lines modified | Offset 768, 8 lines modified | ||
| 768 | -rw----·····2.0·fat·····4307·b-·defN·80-Feb-01·00:00·webencodings/x_user_defined.py | 768 | -rw----·····2.0·fat·····4307·b-·defN·80-Feb-01·00:00·webencodings/x_user_defined.py |
| 769 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/ | 769 | -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/ |
| 770 | -rw----·····2.0·fat·····1039·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/DESCRIPTION.rst | 770 | -rw----·····2.0·fat·····1039·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/DESCRIPTION.rst |
| 771 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/INSTALLER | 771 | -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/INSTALLER |
| 772 | -rw----·····2.0·fat·····2063·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/METADATA | 772 | -rw----·····2.0·fat·····2063·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/METADATA |
| 773 | -rw----·····2.0·fat·····1092·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/metadata.json | 773 | -rw----·····2.0·fat·····1092·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/metadata.json |
| 774 | -rw----·····2.0·fat·······13·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/top_level.txt | 774 | -rw----·····2.0·fat·······13·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/top_level.txt |
| 775 | 773·files,·10 | 775 | 773·files,·10910665·bytes·uncompressed,·3624258·bytes·compressed:··66.8% |
| Offset 906, 27 lines modified | Offset 906, 27 lines modified | ||
| 906 | Filename:·filelock/_soft_rw/_async.py | 906 | Filename:·filelock/_soft_rw/_async.py |
| 907 | Comment:· | 907 | Comment:· |
| 908 | Filename:·filelock/_soft_rw/_sync.py | 908 | Filename:·filelock/_soft_rw/_sync.py |
| 909 | Comment:· | 909 | Comment:· |
| 910 | Filename:·filelock-3.3 | 910 | Filename:·filelock-3.32.2.dist-info/ |
| 911 | Comment:· | 911 | Comment:· |
| 912 | Filename:·filelock-3.3 | 912 | Filename:·filelock-3.32.2.dist-info/INSTALLER |
| 913 | Comment:· | 913 | Comment:· |
| 914 | Filename:·filelock-3.3 | 914 | Filename:·filelock-3.32.2.dist-info/METADATA |
| 915 | Comment:· | 915 | Comment:· |
| 916 | Filename:·filelock-3.3 | 916 | Filename:·filelock-3.32.2.dist-info/licenses/ |
| 917 | Comment:· | 917 | Comment:· |
| 918 | Filename:·filelock-3.3 | 918 | Filename:·filelock-3.32.2.dist-info/licenses/LICENSE |
| 919 | Comment:· | 919 | Comment:· |
| 920 | Filename:·html2text/ | 920 | Filename:·html2text/ |
| 921 | Comment:· | 921 | Comment:· |
| 922 | Filename:·html2text/__init__.py | 922 | Filename:·html2text/__init__.py |
| 923 | Comment:· | 923 | Comment:· |
| Offset 2085, 27 lines modified | Offset 2085, 27 lines modified | ||
| 2085 | Filename:·soupsieve/py.typed | 2085 | Filename:·soupsieve/py.typed |
| 2086 | Comment:· | 2086 | Comment:· |
| 2087 | Filename:·soupsieve/util.py | 2087 | Filename:·soupsieve/util.py |
| 2088 | Comment:· | 2088 | Comment:· |
| 2089 | Filename:·soupsieve-2.9.dist-info/ | 2089 | Filename:·soupsieve-2.9.2.dist-info/ |
| 2090 | Comment:· | 2090 | Comment:· |
| 2091 | Filename:·soupsieve-2.9.dist-info/INSTALLER | 2091 | Filename:·soupsieve-2.9.2.dist-info/INSTALLER |
| 2092 | Comment:· | 2092 | Comment:· |
| 2093 | Filename:·soupsieve-2.9.dist-info/METADATA | 2093 | Filename:·soupsieve-2.9.2.dist-info/METADATA |
| 2094 | Comment:· | 2094 | Comment:· |
| 2095 | Filename:·soupsieve-2.9.dist-info/licenses/ | 2095 | Filename:·soupsieve-2.9.2.dist-info/licenses/ |
| 2096 | Comment:· | 2096 | Comment:· |
| 2097 | Filename:·soupsieve-2.9.dist-info/licenses/LICENSE.md | 2097 | Filename:·soupsieve-2.9.2.dist-info/licenses/LICENSE.md |
| 2098 | Comment:· | 2098 | Comment:· |
| 2099 | Filename:·svglib/ | 2099 | Filename:·svglib/ |
| 2100 | Comment:· | 2100 | Comment:· |
| 2101 | Filename:·svglib/__init__.py | 2101 | Filename:·svglib/__init__.py |
| 2102 | Comment:· | 2102 | Comment:· |
| Offset 2118, 30 lines modified | Offset 2118, 30 lines modified | ||
| 2118 | Filename:·svglib/svglib.py | 2118 | Filename:·svglib/svglib.py |
| 2119 | Comment:· | 2119 | Comment:· |
| 2120 | Filename:·svglib/utils.py | 2120 | Filename:·svglib/utils.py |
| 2121 | Comment:· | 2121 | Comment:· |
| 2122 | Filename:·svglib-2. | 2122 | Filename:·svglib-2.1.0.dist-info/ |
| 2123 | Comment:· | 2123 | Comment:· |
| 2124 | Filename:·svglib-2. | 2124 | Filename:·svglib-2.1.0.dist-info/INSTALLER |
| 2125 | Comment:· | 2125 | Comment:· |
| 2126 | Filename:·svglib-2. | 2126 | Filename:·svglib-2.1.0.dist-info/METADATA |
| 2127 | Comment:· | 2127 | Comment:· |
| 2128 | Filename:·svglib-2. | 2128 | Filename:·svglib-2.1.0.dist-info/entry_points.txt |
| 2129 | Comment:· | 2129 | Comment:· |
| 2130 | Filename:·svglib-2. | 2130 | Filename:·svglib-2.1.0.dist-info/licenses/ |
| 2131 | Comment:· | 2131 | Comment:· |
| 2132 | Filename:·svglib-2. | 2132 | Filename:·svglib-2.1.0.dist-info/licenses/LICENSE.txt |
| 2133 | Comment:· | 2133 | Comment:· |
| 2134 | Filename:·tinycss/ | 2134 | Filename:·tinycss/ |
| 2135 | Comment:· | 2135 | Comment:· |
| 2136 | Filename:·tinycss/__init__.py | 2136 | Filename:·tinycss/__init__.py |
| 2137 | Comment:· | 2137 | Comment:· |
| Offset 6749, 32706 lines modified | Offset 6749, 32706 lines modified | ||
| 6749 | 0F4300·Extract·Zip·Spec······14·(20)·'2.0' | 6749 | 0F4300·Extract·Zip·Spec······14·(20)·'2.0' |
| 6750 | 0F4301·Extract·OS············00·(0)·'MS-DOS' | 6750 | 0F4301·Extract·OS············00·(0)·'MS-DOS' |
| 6751 | 0F4302·General·Purpose·Flag··0800·(2048) | 6751 | 0F4302·General·Purpose·Flag··0800·(2048) |
| 6752 | ·······[Bits·1-2]············0·'Normal·Compression' | 6752 | ·······[Bits·1-2]············0·'Normal·Compression' |
| 6753 | ·······[Bit·11]··············1·'Language·Encoding' | 6753 | ·······[Bit·11]··············1·'Language·Encoding' |
| 6754 | 0F4304·Compression·Method····0008·(8)·'Deflated' | 6754 | 0F4304·Compression·Method····0008·(8)·'Deflated' |
| 6755 | 0F4306·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' | 6755 | 0F4306·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' |
| 6756 | 0F430A·CRC··················· | 6756 | 0F430A·CRC···················013F55B0·(20927920) |
| 6757 | 0F430E·Compressed·Size·······00000 | 6757 | 0F430E·Compressed·Size·······000003EA·(1002) |
| 6758 | 0F4312·Uncompressed·Size·····00000D | 6758 | 0F4312·Uncompressed·Size·····00000D8D·(3469) |
| 6759 | 0F4316·Filename·Length·······0014·(20) | 6759 | 0F4316·Filename·Length·······0014·(20) |
| 6760 | 0F4318·Extra·Length··········0014·(20) | 6760 | 0F4318·Extra·Length··········0014·(20) |
| 6761 | 0F431A·Filename··············'XXXXXXXXXXXXXXXXXXXX' | 6761 | 0F431A·Filename··············'XXXXXXXXXXXXXXXXXXXX' |
| 6762 | # | 6762 | # |
| 6763 | #·WARNING:·Offset·0xF431A:·Filename·'XXXXXXXXXXXXXXXXXXXX' | 6763 | #·WARNING:·Offset·0xF431A:·Filename·'XXXXXXXXXXXXXXXXXXXX' |
| 6764 | #··········Zero·length·filename | 6764 | #··········Zero·length·filename |
| 6765 | # | 6765 | # |
| 6766 | 0F432E·Extra·ID·#1···········0001·(1)·'ZIP64' | 6766 | 0F432E·Extra·ID·#1···········0001·(1)·'ZIP64' |
| 6767 | 0F4330···Length··············0010·(16) | 6767 | 0F4330···Length··············0010·(16) |
| 6768 | 0F4332···Uncompressed·Size···0000000000000D | 6768 | 0F4332···Uncompressed·Size···0000000000000D8D·(3469) |
| 6769 | 0F433A···Compressed·Size·····0000000000000 | 6769 | 0F433A···Compressed·Size·····00000000000003EA·(1002) |
| 6770 | 0F4342·PAYLOAD | 6770 | 0F4342·PAYLOAD |
| 6771 | 0F47 | 6771 | 0F472C·LOCAL·HEADER·#283·····04034B50·(67324752) |
| 6772 | 0F47 | 6772 | 0F4730·Extract·Zip·Spec······14·(20)·'2.0' |
| 6773 | 0F47 | 6773 | 0F4731·Extract·OS············00·(0)·'MS-DOS' |
| 6774 | 0F47 | 6774 | 0F4732·General·Purpose·Flag··0800·(2048) |
| 6775 | ·······[Bits·1-2]············0·'Normal·Compression' | 6775 | ·······[Bits·1-2]············0·'Normal·Compression' |
| 6776 | ·······[Bit·11]··············1·'Language·Encoding' | 6776 | ·······[Bit·11]··············1·'Language·Encoding' |
| 6777 | 0F47 | 6777 | 0F4734·Compression·Method····0008·(8)·'Deflated' |
| 6778 | 0F47 | 6778 | 0F4736·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' |
| 6779 | 0F47 | 6779 | 0F473A·CRC···················A2918A67·(2727447143) |
| 6780 | 0F47 | 6780 | 0F473E·Compressed·Size·······00004E2E·(20014) |
| 6781 | 0F47 | 6781 | 0F4742·Uncompressed·Size·····00014157·(82263) |
| 6782 | 0F47 | 6782 | 0F4746·Filename·Length·······0010·(16) |
| 6783 | 0F47 | 6783 | 0F4748·Extra·Length··········0014·(20) |
| 6784 | 0F47 | 6784 | 0F474A·Filename··············'XXXXXXXXXXXXXXXX' |
| 6785 | # | 6785 | # |
| 6786 | #·WARNING:·Offset·0xF47 | 6786 | #·WARNING:·Offset·0xF474A:·Filename·'XXXXXXXXXXXXXXXX' |
| 6787 | #··········Zero·length·filename | 6787 | #··········Zero·length·filename |
| 6788 | # | 6788 | # |
| 6789 | 0F47 | 6789 | 0F475A·Extra·ID·#1···········0001·(1)·'ZIP64' |
| 6790 | 0F47 | 6790 | 0F475C···Length··············0010·(16) |
| 6791 | 0F47 | 6791 | 0F475E···Uncompressed·Size···0000000000014157·(82263) |
| 6792 | 0F47 | 6792 | 0F4766···Compressed·Size·····0000000000004E2E·(20014) |
| 6793 | 0F47 | 6793 | 0F476E·PAYLOAD |
| 6794 | 0F95 | 6794 | 0F959C·LOCAL·HEADER·#284·····04034B50·(67324752) |
| 6795 | 0F95 | 6795 | 0F95A0·Extract·Zip·Spec······14·(20)·'2.0' |
| 6796 | 0F95 | 6796 | 0F95A1·Extract·OS············00·(0)·'MS-DOS' |
| 6797 | 0F95 | 6797 | 0F95A2·General·Purpose·Flag··0800·(2048) |
| 6798 | ·······[Bits·1-2]············0·'Normal·Compression' | 6798 | ·······[Bits·1-2]············0·'Normal·Compression' |
| 6799 | ·······[Bit·11]··············1·'Language·Encoding' | 6799 | ·······[Bit·11]··············1·'Language·Encoding' |
| 6800 | 0F95 | 6800 | 0F95A4·Compression·Method····0008·(8)·'Deflated' |
| 6801 | 0F95 | 6801 | 0F95A6·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' |
| 6802 | 0F95 | 6802 | 0F95AA·CRC···················4E40F4DE·(1312879838) |
| 6803 | 0F95 | 6803 | 0F95AE·Compressed·Size·······00000673·(1651) |
| 6804 | 0F95 | 6804 | 0F95B2·Uncompressed·Size·····000017DF·(6111) |
| 6805 | 0F95 | 6805 | 0F95B6·Filename·Length·······0012·(18) |
| 6806 | 0F95 | 6806 | 0F95B8·Extra·Length··········0014·(20) |
| 6807 | 0F95 | 6807 | 0F95BA·Filename··············'XXXXXXXXXXXXXXXXXX' |
| 6808 | # | 6808 | # |
| 6809 | #·WARNING:·Offset·0xF95 | 6809 | #·WARNING:·Offset·0xF95BA:·Filename·'XXXXXXXXXXXXXXXXXX' |
| 6810 | #··········Zero·length·filename | 6810 | #··········Zero·length·filename |
| 6811 | # | 6811 | # |
| 6812 | 0F95 | 6812 | 0F95CC·Extra·ID·#1···········0001·(1)·'ZIP64' |
| 6813 | 0F95 | 6813 | 0F95CE···Length··············0010·(16) |
| 6814 | 0F95 | 6814 | 0F95D0···Uncompressed·Size···00000000000017DF·(6111) |
| 6815 | 0F95 | 6815 | 0F95D8···Compressed·Size·····0000000000000673·(1651) |
| 6816 | 0F95 | 6816 | 0F95E0·PAYLOAD |
| 6817 | 0F9 | 6817 | 0F9C53·LOCAL·HEADER·#285·····04034B50·(67324752) |
| 6818 | 0F9C57·Extract·Zip·Spec······14·(20)·'2.0' | ||
| 6819 | 0F9C58·Extract·OS············00·(0)·'MS-DOS' | ||
| 6820 | 0F9C59·General·Purpose·Flag··0800·(2048) | ||
| 6821 | ·······[Bits·1-2]············0·'Normal·Compression' | ||
| 6822 | ·······[Bit·11]··············1·'Language·Encoding' | ||
| 6823 | 0F9C5B·Compression·Method····0008·(8)·'Deflated' | ||
| 6824 | 0F9C5D·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' | ||
| 6825 | 0F9C61·CRC···················03D816F1·(64493297) | ||
| 6826 | 0F9C65·Compressed·Size·······00000CC5·(3269) | ||
| 6827 | 0F9C69·Uncompressed·Size·····0000340D·(13325) | ||
| 6828 | 0F9C6D·Filename·Length·······001D·(29) | ||
| 6829 | 0F9C6F·Extra·Length··········0014·(20) | ||
| 6830 | 0F9C71·Filename··············'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | ||
| 6831 | # | ||
| 6832 | #·WARNING:·Offset·0xF9C71:·Filename·'XXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | ||
| 6833 | #··········Zero·length·filename | ||
| 6834 | # | ||
| 6835 | 0F9C8E·Extra·ID·#1···········0001·(1)·'ZIP64' | ||
| 6836 | 0F9C90···Length··············0010·(16) | ||
| 6837 | 0F9C92···Uncompressed·Size···000000000000340D·(13325) | ||
| 6838 | 0F9C9A···Compressed·Size·····0000000000000CC5·(3269) | ||
| 6839 | 0F9CA2·PAYLOAD | ||
| 6840 | 0FA967·LOCAL·HEADER·#286·····04034B50·(67324752) | ||
| 6841 | 0FA96B·Extract·Zip·Spec······14·(20)·'2.0' | ||
| 6842 | 0FA96C·Extract·OS············00·(0)·'MS-DOS' | ||
| 6843 | 0FA96D·General·Purpose·Flag··0800·(2048) | ||
| 6844 | ·······[Bits·1-2]············0·'Normal·Compression' | ||
| 6845 | ·······[Bit·11]··············1·'Language·Encoding' | ||
| 6846 | 0FA96F·Compression·Method····0008·(8)·'Deflated' | ||
| 6847 | 0FA971·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' | ||
| 6848 | 0FA975·CRC···················39B982A7·(968458919) | ||
| 6849 | 0FA979·Compressed·Size·······000004E6·(1254) | ||
| 6850 | 0FA97D·Uncompressed·Size·····00000BA5·(2981) | ||
| 6851 | 0FA981·Filename·Length·······0017·(23) | ||
| 6852 | 0FA983·Extra·Length··········0014·(20) | ||
| 6853 | 0FA985·Filename··············'XXXXXXXXXXXXXXXXXXXXXXX' | ||
| 6854 | # | ||
| 6855 | #·WARNING:·Offset·0xFA985:·Filename·'XXXXXXXXXXXXXXXXXXXXXXX' | ||
| 6856 | #··········Zero·length·filename | ||
| 6857 | # | ||
| 6858 | 0FA99C·Extra·ID·#1···········0001·(1)·'ZIP64' | ||
| 6859 | 0FA99E···Length··············0010·(16) | ||
| 6860 | 0FA9A0···Uncompressed·Size···0000000000000BA5·(2981) | ||
| 6861 | 0FA9A8···Compressed·Size·····00000000000004E6·(1254) | ||
| 6862 | 0FA9B0·PAYLOAD | ||
| 6863 | 0FAE96·LOCAL·HEADER·#287·····04034B50·(67324752) | ||
| 6818 | 0F | 6864 | 0FAE9A·Extract·Zip·Spec······14·(20)·'2.0' |
| 6819 | 0F | 6865 | 0FAE9B·Extract·OS············00·(0)·'MS-DOS' |
| 6820 | 0F | 6866 | 0FAE9C·General·Purpose·Flag··0800·(2048) |
| 6821 | ·······[Bits·1-2]············0·'Normal·Compression' | 6867 | ·······[Bits·1-2]············0·'Normal·Compression' |
| 6822 | ·······[Bit·11]··············1·'Language·Encoding' | 6868 | ·······[Bit·11]··············1·'Language·Encoding' |
| 6823 | 0F | 6869 | 0FAE9E·Compression·Method····0008·(8)·'Deflated' |
| 6824 | 0F | 6870 | 0FAEA0·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980' |
| Max diff block lines reached; 2595134/2618782 bytes (99.10%) of diff not shown. | |||
| Offset 24, 15 lines modified | Offset 24, 15 lines modified | ||
| 24 | ········AsyncReadWriteLock, | 24 | ········AsyncReadWriteLock, |
| 25 | ····) | 25 | ····) |
| 26 | ····from·._read_write·import·ReadWriteLock | 26 | ····from·._read_write·import·ReadWriteLock |
| 27 | else: | 27 | else: |
| 28 | ····try: | 28 | ····try: |
| 29 | ········from·._async_read_write·import·AsyncAcquireReadWriteReturnProxy,·AsyncReadWriteLock | 29 | ········from·._async_read_write·import·AsyncAcquireReadWriteReturnProxy,·AsyncReadWriteLock |
| 30 | ········from·._read_write·import·ReadWriteLock | 30 | ········from·._read_write·import·ReadWriteLock |
| 31 | ····except·ImportError:··#· | 31 | ····except·ImportError:··#·pragma:·lacks·sqlite3 |
| 32 | ········AsyncAcquireReadWriteReturnProxy·=·None | 32 | ········AsyncAcquireReadWriteReturnProxy·=·None |
| 33 | ········AsyncReadWriteLock·=·None | 33 | ········AsyncReadWriteLock·=·None |
| 34 | ········ReadWriteLock·=·None | 34 | ········ReadWriteLock·=·None |
| 35 | from·._soft·import·SoftFileLock | 35 | from·._soft·import·SoftFileLock |
| 36 | from·._soft_rw·import·AsyncAcquireSoftReadWriteReturnProxy,·AsyncSoftReadWriteLock,·SoftReadWriteLock | 36 | from·._soft_rw·import·AsyncAcquireSoftReadWriteReturnProxy,·AsyncSoftReadWriteLock,·SoftReadWriteLock |
| 37 | from·._strict·import·StrictSoftFileClaim,·StrictSoftFileClaimState,·StrictSoftFileLock | 37 | from·._strict·import·StrictSoftFileClaim,·StrictSoftFileClaimState,·StrictSoftFileLock |
| Offset 392, 25 lines modified | Offset 392, 25 lines modified | ||
| 392 | ········#·rejects·a·legitimate·reentrant·acquire;·the·unguarded·writes·to·the·WeakValueDictionary·are·a·data | 392 | ········#·rejects·a·legitimate·reentrant·acquire;·the·unguarded·writes·to·the·WeakValueDictionary·are·a·data |
| 393 | ········#·race·besides.·ReadWriteLock·and·SoftReadWriteLock·already·guard·their·singleton·caches·this·way. | 393 | ········#·race·besides.·ReadWriteLock·and·SoftReadWriteLock·already·guard·their·singleton·caches·this·way. |
| 394 | ········#·Key·the·cache·on·the·canonical·form·so·equivalent·spellings·of·one·path·share·a·singleton,·and·it·matches·the | 394 | ········#·Key·the·cache·on·the·canonical·form·so·equivalent·spellings·of·one·path·share·a·singleton,·and·it·matches·the |
| 395 | ········#·deadlock-registry·key·acquire()·uses. | 395 | ········#·deadlock-registry·key·acquire()·uses. |
| 396 | ········singleton_key·=·_canonical(lock_file) | 396 | ········singleton_key·=·_canonical(lock_file) |
| 397 | ········with·cls._instances_lock: | 397 | ········with·cls._instances_lock: |
| 398 | ············if·(instance·:=·cls._instances.get(singleton_key))·is·None: | 398 | ············if·(instance·:=·cls._instances.get(singleton_key))·is·None: |
| 399 | ················if·singleton_key·in·cls._instances_under_construction: | 399 | ················if·singleton_key·in·cls._instances_under_construction:··#·pragma:·needs·fork |
| 400 | ····················msg·=·f"Singleton·lock·construction·is·already·active·for·{lock_file!s}" | 400 | ····················msg·=·f"Singleton·lock·construction·is·already·active·for·{lock_file!s}" |
| 401 | ····················raise·RuntimeError(msg) | 401 | ····················raise·RuntimeError(msg) |
| 402 | ················construction_registry·=·cls._instances_under_construction | 402 | ················construction_registry·=·cls._instances_under_construction |
| 403 | ················construction_pid·=·os.getpid() | 403 | ················construction_pid·=·os.getpid() |
| 404 | ················construction_registry.add(singleton_key) | 404 | ················construction_registry.add(singleton_key) |
| 405 | ················try: | 405 | ················try: |
| 406 | ····················instance·=·cls._create_instance(lock_file,·params) | 406 | ····················instance·=·cls._create_instance(lock_file,·params) |
| 407 | ················finally: | 407 | ················finally: |
| 408 | ····················construction_registry.discard(singleton_key) | 408 | ····················construction_registry.discard(singleton_key) |
| 409 | ················if·os.getpid()·!=·construction_pid: | 409 | ················if·os.getpid()·!=·construction_pid:··#·pragma:·needs·fork |
| 410 | ····················msg·=·"Lock·construction·cannot·continue·after·fork;·construct·a·new·lock·in·the·child" | 410 | ····················msg·=·"Lock·construction·cannot·continue·after·fork;·construct·a·new·lock·in·the·child" |
| 411 | ····················raise·RuntimeError(msg) | 411 | ····················raise·RuntimeError(msg) |
| 412 | ················cls._instances[singleton_key]·=·instance | 412 | ················cls._instances[singleton_key]·=·instance |
| 413 | ················return·instance | 413 | ················return·instance |
| 414 | ········params_to_check·=·{ | 414 | ········params_to_check·=·{ |
| 415 | ············"thread_local":·(thread_local,·instance.is_thread_local()), | 415 | ············"thread_local":·(thread_local,·instance.is_thread_local()), |
| Offset 633, 15 lines modified | Offset 633, 15 lines modified | ||
| 633 | ········super().__init_subclass__(**kwargs) | 633 | ········super().__init_subclass__(**kwargs) |
| 634 | ········cls._instances·=·WeakValueDictionary() | 634 | ········cls._instances·=·WeakValueDictionary() |
| 635 | ········cls._instances_lock·=·RLock() | 635 | ········cls._instances_lock·=·RLock() |
| 636 | ········cls._instances_under_construction·=·set() | 636 | ········cls._instances_under_construction·=·set() |
| 637 | ········_register_fork_class(cls) | 637 | ········_register_fork_class(cls) |
| 638 | ····@classmethod | 638 | ····@classmethod |
| 639 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:· | 639 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·forked·child |
| 640 | ········cls._instances·=·WeakValueDictionary() | 640 | ········cls._instances·=·WeakValueDictionary() |
| 641 | ········cls._instances_lock·=·RLock() | 641 | ········cls._instances_lock·=·RLock() |
| 642 | ········cls._instances_under_construction·=·set() | 642 | ········cls._instances_under_construction·=·set() |
| 643 | ····def·__init__(··#·ruff:ignore[too-many-arguments]··#·public·constructor:·one·parameter·per·documented·lock·option | 643 | ····def·__init__(··#·ruff:ignore[too-many-arguments]··#·public·constructor:·one·parameter·per·documented·lock·option |
| 644 | ········self, | 644 | ········self, |
| 645 | ········lock_file:·str·|·os.PathLike[str], | 645 | ········lock_file:·str·|·os.PathLike[str], |
| Offset 967, 15 lines modified | Offset 967, 15 lines modified | ||
| 967 | ············if·body_error·is·None·or·self._context_error_policy·==·"chain": | 967 | ············if·body_error·is·None·or·self._context_error_policy·==·"chain": |
| 968 | ················raise | 968 | ················raise |
| 969 | ············_raise_body_and_release(body_error,·release_error) | 969 | ············_raise_body_and_release(body_error,·release_error) |
| 970 | ····def·__del__(self)·->·None: | 970 | ····def·__del__(self)·->·None: |
| 971 | ········"""Force-release·so·a·dropped·reference·never·leaks·a·held·lock.""" | 971 | ········"""Force-release·so·a·dropped·reference·never·leaks·a·held·lock.""" |
| 972 | ········if·vars(self).get("_creator_pid")·!=·os.getpid(): | 972 | ········if·vars(self).get("_creator_pid")·!=·os.getpid(): |
| 973 | ············return··#·pragma:· | 973 | ············return··#·pragma:·forked·child |
| 974 | ········#·A·finalizer·must·not·raise.·A·release·error·during·garbage·collection·would·otherwise·surface·as·an | 974 | ········#·A·finalizer·must·not·raise.·A·release·error·during·garbage·collection·would·otherwise·surface·as·an |
| 975 | ········#·unraisable-exception·warning,·attributed·to·whichever·code·triggered·collection.·The·dropped·lock·still·gets | 975 | ········#·unraisable-exception·warning,·attributed·to·whichever·code·triggered·collection.·The·dropped·lock·still·gets |
| 976 | ········#·best-effort·cleanup;·an·explicit·release()·reports·the·same·error·to·a·caller·who·can·act·on·it. | 976 | ········#·best-effort·cleanup;·an·explicit·release()·reports·the·same·error·to·a·caller·who·can·act·on·it. |
| 977 | ········with·contextlib.suppress(Exception): | 977 | ········with·contextlib.suppress(Exception): |
| 978 | ············self.release(force=True) | 978 | ············self.release(force=True) |
| 979 | ····def·acquire( | 979 | ····def·acquire( |
| Offset 1079, 23 lines modified | Offset 1079, 23 lines modified | ||
| 1079 | ····)·->·Generator[None]: | 1079 | ····)·->·Generator[None]: |
| 1080 | ········#·One·thread·at·a·time·drives·the·physical·transition·of·a·shared·instance.·A·protocol·that·publishes·several | 1080 | ········#·One·thread·at·a·time·drives·the·physical·transition·of·a·shared·instance.·A·protocol·that·publishes·several |
| 1081 | ········#·files·per·owner·leaves·a·half-built·claim·visible·otherwise,·and·a·second·thread·would·read·it·as·a·holder. | 1081 | ········#·files·per·owner·leaves·a·half-built·claim·visible·otherwise,·and·a·second·thread·would·read·it·as·a·holder. |
| 1082 | ········#·Only·such·a·backend·opts·in;·a·single-file·backend·and·a·thread-local·context·each·need·no·gate. | 1082 | ········#·Only·such·a·backend·opts·in;·a·single-file·backend·and·a·thread-local·context·each·need·no·gate. |
| 1083 | ········if·not·self._serialize_transitions·or·self._is_thread_local: | 1083 | ········if·not·self._serialize_transitions·or·self._is_thread_local: |
| 1084 | ············yield | 1084 | ············yield |
| 1085 | ············return | 1085 | ············return |
| 1086 | ········while·not·self._transition_lock.acquire(blocking=False): | 1086 | ········while·not·self._transition_lock.acquire(blocking=False):··#·pragma:·needs·hard-link |
| 1087 | ············if·not·blocking·or·(cancel_check·is·not·None·and·cancel_check()): | 1087 | ············if·not·blocking·or·(cancel_check·is·not·None·and·cancel_check()): |
| 1088 | ················raise·Timeout(self.lock_file) | 1088 | ················raise·Timeout(self.lock_file) |
| 1089 | ············if·timeout·>=·0·and·time.perf_counter()·-·start_time·>=·timeout: | 1089 | ············if·timeout·>=·0·and·time.perf_counter()·-·start_time·>=·timeout: |
| 1090 | ················raise·Timeout(self.lock_file) | 1090 | ················raise·Timeout(self.lock_file) |
| 1091 | ············time.sleep(poll_interval) | 1091 | ············time.sleep(poll_interval) |
| 1092 | ········try: | 1092 | ········try:··#·pragma:·needs·hard-link |
| 1093 | ············yield | 1093 | ············yield |
| 1094 | ········finally: | 1094 | ········finally:··#·pragma:·needs·hard-link |
| 1095 | ············self._transition_lock.release() | 1095 | ············self._transition_lock.release() |
| 1096 | ····def·release(self,·force:·bool·=·False)·->·None:··#·ruff:ignore[boolean-type-hint-positional-argument,·boolean-default-value-positional-argument]··#·public·API:·positional·bool·kept·for·backwards·compatibility | 1096 | ····def·release(self,·force:·bool·=·False)·->·None:··#·ruff:ignore[boolean-type-hint-positional-argument,·boolean-default-value-positional-argument]··#·public·API:·positional·bool·kept·for·backwards·compatibility |
| 1097 | ········""" | 1097 | ········""" |
| 1098 | ········Release·the·file·lock.·The·lock·is·only·completely·released·when·the·lock·counter·reaches·0.·The·lock·file | 1098 | ········Release·the·file·lock.·The·lock·is·only·completely·released·when·the·lock·counter·reaches·0.·The·lock·file |
| 1099 | ········itself·may·be·deleted·automatically,·the·behavior·is·platform-specific. | 1099 | ········itself·may·be·deleted·automatically,·the·behavior·is·platform-specific. |
| Offset 1123, 15 lines modified | Offset 1123, 15 lines modified | ||
| 1123 | ················if·not·self.is_locked: | 1123 | ················if·not·self.is_locked: |
| 1124 | ····················self._commit_release() | 1124 | ····················self._commit_release() |
| 1125 | ················raise | 1125 | ················raise |
| 1126 | ············self._commit_release() | 1126 | ············self._commit_release() |
| 1127 | ············_LOGGER.debug("Lock·%s·released·on·%s",·lock_id,·lock_filename) | 1127 | ············_LOGGER.debug("Lock·%s·released·on·%s",·lock_id,·lock_filename) |
| 1128 | ····def·_raise_if_inherited(self)·->·None: | 1128 | ····def·_raise_if_inherited(self)·->·None: |
| 1129 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:· | 1129 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child |
| 1130 | ············msg·=·f"{type(self).__name__}·on·{self.lock_file}·was·inherited·across·fork;·construct·a·new·instance" | 1130 | ············msg·=·f"{type(self).__name__}·on·{self.lock_file}·was·inherited·across·fork;·construct·a·new·instance" |
| 1131 | ············raise·RuntimeError(msg) | 1131 | ············raise·RuntimeError(msg) |
| 1132 | ····def·_mark_descriptor_owned(self,·fd:·int,·identity:·tuple[int,·int]·|·None·=·None)·->·None: | 1132 | ····def·_mark_descriptor_owned(self,·fd:·int,·identity:·tuple[int,·int]·|·None·=·None)·->·None: |
| 1133 | ········self._context.pending_lock_file_fd·=·None | 1133 | ········self._context.pending_lock_file_fd·=·None |
| 1134 | ········self._context.pending_lock_file_fd_identity·=·None | 1134 | ········self._context.pending_lock_file_fd_identity·=·None |
| 1135 | ········self._context.lock_file_fd·=·fd | 1135 | ········self._context.lock_file_fd·=·fd |
| Offset 1143, 28 lines modified | Offset 1143, 28 lines modified | ||
| 1143 | ····def·_mark_descriptor_released(self)·->·None: | 1143 | ····def·_mark_descriptor_released(self)·->·None: |
| 1144 | ········self._context.pending_lock_file_fd·=·None | 1144 | ········self._context.pending_lock_file_fd·=·None |
| 1145 | ········self._context.pending_lock_file_fd_identity·=·None | 1145 | ········self._context.pending_lock_file_fd_identity·=·None |
| 1146 | ········self._context.lock_file_fd·=·None | 1146 | ········self._context.lock_file_fd·=·None |
| 1147 | ········self._context.lock_file_fd_identity·=·None | 1147 | ········self._context.lock_file_fd_identity·=·None |
| 1148 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:· | 1148 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·forked·child |
| 1149 | ········#·fork·copies·the·lock·in·whatever·state·the·parent's·threads·left·it,·so·give·the·child·an·unheld·one. | 1149 | ········#·fork·copies·the·lock·in·whatever·state·the·parent's·threads·left·it,·so·give·the·child·an·unheld·one. |
| 1150 | ········self._transition_lock·=·RLock() | 1150 | ········self._transition_lock·=·RLock() |
| 1151 | ········self._context.owner_claim_paths·=·() | 1151 | ········self._context.owner_claim_paths·=·() |
| 1152 | ········self._context.claim_root·=·None | 1152 | ········self._context.claim_root·=·None |
| 1153 | ········self._context.lock_file_fd·=·None | 1153 | ········self._context.lock_file_fd·=·None |
| 1154 | ········self._context.lock_file_fd_token·=·None | 1154 | ········self._context.lock_file_fd_token·=·None |
| 1155 | ········self._context.lock_file_fd_identity·=·None | 1155 | ········self._context.lock_file_fd_identity·=·None |
| 1156 | ········self._context.pending_lock_file_fd·=·None | 1156 | ········self._context.pending_lock_file_fd·=·None |
| 1157 | ········self._context.pending_lock_file_fd_identity·=·None | 1157 | ········self._context.pending_lock_file_fd_identity·=·None |
| 1158 | ········self._context.lock_counter·=·0 | 1158 | ········self._context.lock_counter·=·0 |
| 1159 | ········self._context.lock_file_key·=·None | 1159 | ········self._context.lock_file_key·=·None |
| 1160 | ····def·_descriptors_for_fork(self)·->·tuple[tuple[int,·tuple[int,·int]·|·None],·...]: | 1160 | ····def·_descriptors_for_fork(self)·->·tuple[tuple[int,·tuple[int,·int]·|·None],·...]:··#·pragma:·needs·fork |
| 1161 | ········descriptors:·list[tuple[int,·tuple[int,·int]·|·None]]·=·[] | 1161 | ········descriptors:·list[tuple[int,·tuple[int,·int]·|·None]]·=·[] |
| 1162 | ········if·self._context.lock_file_fd·is·not·None·and·self._context.lock_file_fd_token·is·None: | 1162 | ········if·self._context.lock_file_fd·is·not·None·and·self._context.lock_file_fd_token·is·None: |
| 1163 | ············descriptors.append((self._context.lock_file_fd,·self._context.lock_file_fd_identity)) | 1163 | ············descriptors.append((self._context.lock_file_fd,·self._context.lock_file_fd_identity)) |
| 1164 | ········if·self._context.pending_lock_file_fd·is·not·None: | 1164 | ········if·self._context.pending_lock_file_fd·is·not·None: |
| 1165 | ············descriptors.append((self._context.pending_lock_file_fd,·self._context.pending_lock_file_fd_identity)) | 1165 | ············descriptors.append((self._context.pending_lock_file_fd,·self._context.pending_lock_file_fd_identity)) |
| 1166 | ········return·tuple(descriptors) | 1166 | ········return·tuple(descriptors) |
| Offset 1237, 16 lines modified | Offset 1237, 18 lines modified | ||
| Max diff block lines reached; 16618/24156 bytes (68.79%) of diff not shown. | |||
| Offset 4, 15 lines modified | Offset 4, 17 lines modified | ||
| 4 | import·asyncio | 4 | import·asyncio |
| 5 | import·contextlib | 5 | import·contextlib |
| 6 | import·time | 6 | import·time |
| 7 | from·concurrent.futures·import·Future·as·ConcurrentFuture | 7 | from·concurrent.futures·import·Future·as·ConcurrentFuture |
| 8 | from·dataclasses·import·dataclass | 8 | from·dataclasses·import·dataclass |
| 9 | from·threading·import·Lock | 9 | from·threading·import·Lock |
| 10 | from·typing·import·TYPE_CHECKING,·Final,·Generic,·TypeVar,·cast | 10 | from·typing·import·TYPE_CHECKING,·Final,·Generic,·NoReturn,·TypeVar,·cast |
| 11 | from·._api·import·_append_exception_context,·_raise_chained_errors | ||
| 11 | if·TYPE_CHECKING: | 12 | if·TYPE_CHECKING: |
| 12 | ····from·collections.abc·import·AsyncIterator,·Awaitable,·Callable | 13 | ····from·collections.abc·import·AsyncIterator,·Awaitable,·Callable |
| 13 | _T·=·TypeVar("_T") | 14 | _T·=·TypeVar("_T") |
| Offset 135, 14 lines modified | Offset 137, 26 lines modified | ||
| 135 | def·_capture_call(func:·Callable[[],·_T])·->·_BackendOutcome[_T]: | 137 | def·_capture_call(func:·Callable[[],·_T])·->·_BackendOutcome[_T]: |
| 136 | ····try: | 138 | ····try: |
| 137 | ········return·_BackendOutcome(value=func()) | 139 | ········return·_BackendOutcome(value=func()) |
| 138 | ····except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·backend·control-flow·exceptions·are·operation·results | 140 | ····except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·backend·control-flow·exceptions·are·operation·results |
| 139 | ········return·_BackendOutcome(error=error) | 141 | ········return·_BackendOutcome(error=error) |
| 142 | def·_raise_cancelled_error(cancellation:·asyncio.CancelledError,·error:·BaseException)·->·NoReturn: | ||
| 143 | ····#·A·reconciliation·step·failed·while·unwinding·a·cancellation,·so·keep·both·exception·chains.·Splice·the·error's | ||
| 144 | ····#·existing·context·onto·the·cancellation,·then·make·the·cancellation·the·error's·context,·so·both·the·failure·and | ||
| 145 | ····#·the·cancellation·that·triggered·it·survive.·Shared·by·the·async·wrappers·so·cancellations·report·the·same·way. | ||
| 146 | ····if·(context·:=·error.__context__)·is·not·None·and·context·is·not·cancellation: | ||
| 147 | ········if·(cancellation_context·:=·cancellation.__context__)·is·not·None: | ||
| 148 | ············_append_exception_context(context,·cancellation_context) | ||
| 149 | ········cancellation.__context__·=·context | ||
| 150 | ····error.__context__·=·cancellation | ||
| 151 | ····_raise_chained_errors(error) | ||
| 140 | async·def·_capture_awaitable(awaitable:·Awaitable[_T])·->·_BackendOutcome[_T]: | 152 | async·def·_capture_awaitable(awaitable:·Awaitable[_T])·->·_BackendOutcome[_T]: |
| 141 | ····try: | 153 | ····try: |
| 142 | ········return·_BackendOutcome(value=await·awaitable) | 154 | ········return·_BackendOutcome(value=await·awaitable) |
| 143 | ····except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·backend·cancellation·must·remain·distinct·from·caller·cancellation | 155 | ····except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·backend·cancellation·must·remain·distinct·from·caller·cancellation |
| 144 | ········return·_BackendOutcome(error=error) | 156 | ········return·_BackendOutcome(error=error) |
| Offset 150, 9 lines modified | Offset 164, 10 lines modified | ||
| 150 | ····"_AsyncTransitionGate", | 164 | ····"_AsyncTransitionGate", |
| 151 | ····"_AsyncTransitionUnavailableError", | 165 | ····"_AsyncTransitionUnavailableError", |
| 152 | ····"_BackendOutcome", | 166 | ····"_BackendOutcome", |
| 153 | ····"_capture_awaitable", | 167 | ····"_capture_awaitable", |
| 154 | ····"_capture_call", | 168 | ····"_capture_call", |
| 155 | ····"_drain_future", | 169 | ····"_drain_future", |
| 156 | ····"_future_result", | 170 | ····"_future_result", |
| 171 | ····"_raise_cancelled_error", | ||
| 157 | ····"_wait_until_done", | 172 | ····"_wait_until_done", |
| 158 | ] | 173 | ] |
| Offset 10, 25 lines modified | Offset 10, 30 lines modified | ||
| 10 | from·contextlib·import·asynccontextmanager | 10 | from·contextlib·import·asynccontextmanager |
| 11 | from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar | 11 | from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar |
| 12 | from·._api·import·( | 12 | from·._api·import·( |
| 13 | ····_append_exception_context, | 13 | ····_append_exception_context, |
| 14 | ····_ensure_current_process, | 14 | ····_ensure_current_process, |
| 15 | ····_fork_transition, | 15 | ····_fork_transition, |
| 16 | ····_raise_chained_errors, | ||
| 17 | ····_register_fork_object, | 16 | ····_register_fork_object, |
| 18 | ) | 17 | ) |
| 19 | from·._async·import· | 18 | from·._async·import·( |
| 19 | ····_BackendOutcome, | ||
| 20 | ····_capture_call, | ||
| 21 | ····_drain_future, | ||
| 22 | ····_future_result, | ||
| 23 | ····_raise_cancelled_error, | ||
| 24 | ····_wait_until_done, | ||
| 25 | ) | ||
| 20 | from·._read_write·import·ReadWriteLock | 26 | from·._read_write·import·ReadWriteLock |
| 21 | if·TYPE_CHECKING: | 27 | if·TYPE_CHECKING: |
| 22 | ····from·collections.abc·import·AsyncGenerator,·Callable | 28 | ····from·collections.abc·import·AsyncGenerator,·Callable |
| 23 | ····from·concurrent·import·futures | 29 | ····from·concurrent·import·futures |
| 24 | ····from·types·import·TracebackType | 30 | ····from·types·import·TracebackType |
| 25 | ····from·typing·import·NoReturn | ||
| 26 | ····from·._api·import·AcquireReturnProxy | 31 | ····from·._api·import·AcquireReturnProxy |
| 27 | _P·=·ParamSpec("_P") | 32 | _P·=·ParamSpec("_P") |
| 28 | _R·=·TypeVar("_R") | 33 | _R·=·TypeVar("_R") |
| Offset 70, 15 lines modified | Offset 75, 15 lines modified | ||
| 70 | ········self._closed·=·False | 75 | ········self._closed·=·False |
| 71 | ········_register_fork_object(self) | 76 | ········_register_fork_object(self) |
| 72 | ········with·_fork_transition(): | 77 | ········with·_fork_transition(): |
| 73 | ············self._lock·=·ReadWriteLock(lock_file,·timeout,·blocking=blocking,·is_singleton=is_singleton) | 78 | ············self._lock·=·ReadWriteLock(lock_file,·timeout,·blocking=blocking,·is_singleton=is_singleton) |
| 74 | ············self._loop·=·loop | 79 | ············self._loop·=·loop |
| 75 | ············self._owns_executor·=·executor·is·None | 80 | ············self._owns_executor·=·executor·is·None |
| 76 | ············self._executor·=·executor·or·ThreadPoolExecutor(max_workers=1) | 81 | ············self._executor·=·executor·or·ThreadPoolExecutor(max_workers=1) |
| 77 | ············if·os.getpid()·!=·creator_pid:··#·pragma:· | 82 | ············if·os.getpid()·!=·creator_pid:··#·pragma:·forked·child |
| 78 | ················msg·=·"AsyncReadWriteLock·construction·cannot·continue·after·fork" | 83 | ················msg·=·"AsyncReadWriteLock·construction·cannot·continue·after·fork" |
| 79 | ················raise·RuntimeError(msg) | 84 | ················raise·RuntimeError(msg) |
| 80 | ····@property | 85 | ····@property |
| 81 | ····def·lock_file(self)·->·str: | 86 | ····def·lock_file(self)·->·str: |
| 82 | ········"""The·path·to·the·lock·file.""" | 87 | ········"""The·path·to·the·lock·file.""" |
| 83 | ········return·self._lock.lock_file | 88 | ········return·self._lock.lock_file |
| Offset 207, 111 lines modified | Offset 212, 103 lines modified | ||
| 207 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level | 212 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level |
| 208 | ········:raises·RuntimeError:·if·no·lock·is·currently·held·and·*force*·is·``False`` | 213 | ········:raises·RuntimeError:·if·no·lock·is·currently·held·and·*force*·is·``False`` |
| 209 | ········""" | 214 | ········""" |
| 210 | ········_ensure_current_process() | 215 | ········_ensure_current_process() |
| 211 | ········if·self._inherited: | 216 | ········if·self._inherited:··#·pragma:·needs·fork |
| 212 | ············return | 217 | ············return |
| 213 | ········await·self._run(self._lock.release,·force=force) | 218 | ········await·self._run(self._lock.release,·force=force) |
| 214 | ····async·def·close(self)·->·None: | 219 | ····async·def·close(self)·->·None: |
| 215 | ········""" | 220 | ········""" |
| 216 | ········Release·the·lock·(if·held)·and·close·the·underlying·SQLite·connection. | 221 | ········Release·the·lock·(if·held)·and·close·the·underlying·SQLite·connection. |
| 217 | ········After·calling·this·method,·the·lock·instance·is·no·longer·usable. | 222 | ········After·calling·this·method,·the·lock·instance·is·no·longer·usable. |
| 218 | ········""" | 223 | ········""" |
| 219 | ········_ensure_current_process() | 224 | ········_ensure_current_process() |
| 220 | ········if·self._inherited: | 225 | ········if·self._inherited:··#·pragma:·needs·fork |
| 221 | ············return | 226 | ············return |
| 222 | ········if·self._closed: | 227 | ········if·self._closed: |
| 223 | ············return | 228 | ············return |
| 224 | ········close_future·=·self._submit(self._lock.close) | 229 | ········close_future·=·self._submit(self._lock.close) |
| 225 | ········try: | 230 | ········try: |
| 226 | ············await·_wait_until_done(close_future) | 231 | ············await·_wait_until_done(close_future) |
| 227 | ········except·asyncio.CancelledError·as·cancellation: | 232 | ········except·asyncio.CancelledError·as·cancellation: |
| 228 | ············try: | 233 | ············try: |
| 229 | ················await·_drain_future(close_future) | 234 | ················await·_drain_future(close_future) |
| 230 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | 235 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below |
| 231 | ················ | 236 | ················_raise_cancelled_error(cancellation,·error) |
| 232 | ············self._closed·=·True | 237 | ············self._closed·=·True |
| 233 | ············self._shutdown_owned_executor() | 238 | ············self._shutdown_owned_executor() |
| 234 | ············raise | 239 | ············raise |
| 235 | ········_future_result(close_future) | 240 | ········_future_result(close_future) |
| 236 | ········self._closed·=·True | 241 | ········self._closed·=·True |
| 237 | ········ | 242 | ········#·Wait·for·the·worker·to·exit·rather·than·letting·it·drain·in·the·background:·a·caller·that·forks·right |
| 243 | ········#·after·closing·deserves·a·single-threaded·process,·and·os.fork·warns·about·any·surviving·thread. | ||
| 244 | ········if·self._owns_executor: | ||
| 245 | ············await·asyncio.to_thread(functools.partial(self._executor.shutdown,·wait=True)) | ||
| 238 | ····async·def·_run_acquire(self,·acquire:·Callable[[],·AcquireReturnProxy])·->·None: | 246 | ····async·def·_run_acquire(self,·acquire:·Callable[[],·AcquireReturnProxy])·->·None: |
| 239 | ········acquire_future·=·self._submit(acquire) | 247 | ········acquire_future·=·self._submit(acquire) |
| 240 | ········try: | 248 | ········try: |
| 241 | ············await·_wait_until_done(acquire_future) | 249 | ············await·_wait_until_done(acquire_future) |
| 242 | ········except·asyncio.CancelledError·as·cancellation: | 250 | ········except·asyncio.CancelledError·as·cancellation: |
| 243 | ············try: | 251 | ············try: |
| 244 | ················await·_drain_future(acquire_future) | 252 | ················await·_drain_future(acquire_future) |
| 245 | ············except·asyncio.CancelledError·as·acquire_error: | ||
| 246 | ················self._raise_cancelled_error(cancellation,·acquire_error) | ||
| 247 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | 253 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below |
| 248 | ················ | 254 | ················_raise_cancelled_error(cancellation,·error) |
| 249 | ············try: | 255 | ············try: |
| 250 | ················await·_drain_future(self._submit(self._lock.release)) | 256 | ················await·_drain_future(self._submit(self._lock.release)) |
| 251 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | 257 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below |
| 252 | ················ | 258 | ················_raise_cancelled_error(cancellation,·error) |
| 253 | ············raise | 259 | ············raise |
| 254 | ········_future_result(acquire_future) | 260 | ········_future_result(acquire_future) |
| 255 | ····async·def·_run(self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs)·->·_R: | 261 | ····async·def·_run(self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs)·->·_R: |
| 256 | ········future·=·self._submit(func,·*args,·**kwargs) | 262 | ········future·=·self._submit(func,·*args,·**kwargs) |
| 257 | ········try: | 263 | ········try: |
| 258 | ············await·_wait_until_done(future) | 264 | ············await·_wait_until_done(future) |
| 259 | ········except·asyncio.CancelledError·as·cancellation: | 265 | ········except·asyncio.CancelledError·as·cancellation: |
| 260 | ············try: | 266 | ············try: |
| 261 | ················await·_drain_future(future) | 267 | ················await·_drain_future(future) |
| 262 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | 268 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below |
| 263 | ················ | 269 | ················_raise_cancelled_error(cancellation,·error) |
| 264 | ············raise | 270 | ············raise |
| 265 | ········return·_future_result(future) | 271 | ········return·_future_result(future) |
| 266 | ····def·_submit( | 272 | ····def·_submit( |
| 267 | ········self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs | 273 | ········self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs |
| 268 | ····)·->·asyncio.Future[_BackendOutcome[_R]]: | 274 | ····)·->·asyncio.Future[_BackendOutcome[_R]]: |
| 269 | ········return·(self._loop·or·asyncio.get_running_loop()).run_in_executor( | 275 | ········return·(self._loop·or·asyncio.get_running_loop()).run_in_executor( |
| 270 | ············self._executor, | 276 | ············self._executor, |
| 271 | ············_capture_call, | 277 | ············_capture_call, |
| 272 | ············functools.partial(func,·*args,·**kwargs), | 278 | ············functools.partial(func,·*args,·**kwargs), |
| Max diff block lines reached; 1782/7386 bytes (24.13%) of diff not shown. | |||
| Offset 8, 15 lines modified | Offset 8, 15 lines modified | ||
| 8 | ········super().__init__() | 8 | ········super().__init__() |
| 9 | ········self._lock_file·=·lock_file | 9 | ········self._lock_file·=·lock_file |
| 10 | ····def·__reduce__(self)·->·tuple[type[Timeout],·tuple[str]]: | 10 | ····def·__reduce__(self)·->·tuple[type[Timeout],·tuple[str]]: |
| 11 | ········#·__init__·needs·lock_file,·so·pickle·must·restore·it·as·a·constructor·arg | 11 | ········#·__init__·needs·lock_file,·so·pickle·must·restore·it·as·a·constructor·arg |
| 12 | ········return·self.__class__,·(self._lock_file,) | 12 | ········return·self.__class__,·(self._lock_file,) |
| 13 | ····def·__str__(self)·->·str: | 13 | ····def·__str__(self)·->·str:··#·pragma:·needs·hard-link |
| 14 | ········return·f"The·file·lock·'{self._lock_file}'·could·not·be·acquired." | 14 | ········return·f"The·file·lock·'{self._lock_file}'·could·not·be·acquired." |
| 15 | ····def·__repr__(self)·->·str: | 15 | ····def·__repr__(self)·->·str: |
| 16 | ········return·f"{self.__class__.__name__}({self.lock_file!r})" | 16 | ········return·f"{self.__class__.__name__}({self.lock_file!r})" |
| 17 | ····@property | 17 | ····@property |
| 18 | ····def·lock_file(self)·->·str: | 18 | ····def·lock_file(self)·->·str: |
| Offset 37, 33 lines modified | Offset 37, 35 lines modified | ||
| 37 | ····def·__init__(self,·lock_file:·str,·claim_name:·str·|·None,·reason:·str)·->·None: | 37 | ····def·__init__(self,·lock_file:·str,·claim_name:·str·|·None,·reason:·str)·->·None: |
| 38 | ········self._lock_file·=·lock_file | 38 | ········self._lock_file·=·lock_file |
| 39 | ········self._claim_name·=·claim_name | 39 | ········self._claim_name·=·claim_name |
| 40 | ········self._reason·=·reason | 40 | ········self._reason·=·reason |
| 41 | ········super().__init__(self.__str__()) | 41 | ········super().__init__(self.__str__()) |
| 42 | ····def·__reduce__( | ||
| 43 | ········self, | ||
| 42 | ···· | 44 | ····)·->·tuple[type[SoftFileLockProtocolError],·tuple[str,·str·|·None,·str]]:··#·pragma:·needs·hard-link |
| 43 | ········return·self.__class__,·(self._lock_file,·self._claim_name,·self._reason) | 45 | ········return·self.__class__,·(self._lock_file,·self._claim_name,·self._reason) |
| 44 | ····def·__str__(self)·->·str: | 46 | ····def·__str__(self)·->·str: |
| 45 | ········location·=·self._lock_file·if·self._claim_name·is·None·else·f"{self._lock_file}:·claim·{self._claim_name!r}" | 47 | ········location·=·self._lock_file·if·self._claim_name·is·None·else·f"{self._lock_file}:·claim·{self._claim_name!r}" |
| 46 | ········return·f"Invalid·strict·soft-lock·state·at·{location}:·{self._reason}" | 48 | ········return·f"Invalid·strict·soft-lock·state·at·{location}:·{self._reason}" |
| 47 | ····@property | 49 | ····@property |
| 48 | ····def·lock_file(self)·->·str: | 50 | ····def·lock_file(self)·->·str:··#·pragma:·needs·hard-link |
| 49 | ········"""The·requested·lock·path.""" | 51 | ········"""The·requested·lock·path.""" |
| 50 | ········return·self._lock_file | 52 | ········return·self._lock_file |
| 51 | ····@property | 53 | ····@property |
| 52 | ····def·claim_name(self)·->·str·|·None: | 54 | ····def·claim_name(self)·->·str·|·None:··#·pragma:·needs·hard-link |
| 53 | ········"""The·claim·that·caused·the·error,·if·scanning·identified·one.""" | 55 | ········"""The·claim·that·caused·the·error,·if·scanning·identified·one.""" |
| 54 | ········return·self._claim_name | 56 | ········return·self._claim_name |
| 55 | ····@property | 57 | ····@property |
| 56 | ····def·reason(self)·->·str: | 58 | ····def·reason(self)·->·str:··#·pragma:·needs·hard-link |
| 57 | ········"""The·protocol·validation·failure.""" | 59 | ········"""The·protocol·validation·failure.""" |
| 58 | ········return·self._reason | 60 | ········return·self._reason |
| 59 | __all__·=·[ | 61 | __all__·=·[ |
| 60 | ····"LeaseSettingsMismatch", | 62 | ····"LeaseSettingsMismatch", |
| 61 | ····"SoftFileLockLifetimeWarning", | 63 | ····"SoftFileLockLifetimeWarning", |
| Offset 74, 15 lines modified | Offset 74, 15 lines modified | ||
| 74 | ············if·not·_KERNEL32.GetProcessTimes( | 74 | ············if·not·_KERNEL32.GetProcessTimes( |
| 75 | ················handle, | 75 | ················handle, |
| 76 | ················ctypes.byref(creation), | 76 | ················ctypes.byref(creation), |
| 77 | ················ctypes.byref(exit_time), | 77 | ················ctypes.byref(exit_time), |
| 78 | ················ctypes.byref(kernel_time), | 78 | ················ctypes.byref(kernel_time), |
| 79 | ················ctypes.byref(user_time), | 79 | ················ctypes.byref(user_time), |
| 80 | ············): | 80 | ············): |
| 81 | ················return·None | 81 | ················return·None··#·pragma:·no·cover··#·win32·GetProcessTimes·failure·path;·not·reproducible·on·a·live·handle |
| 82 | ········finally: | 82 | ········finally: |
| 83 | ············_KERNEL32.CloseHandle(handle) | 83 | ············_KERNEL32.CloseHandle(handle) |
| 84 | ········return·(creation.dwHighDateTime·<<·32)·|·creation.dwLowDateTime | 84 | ········return·(creation.dwHighDateTime·<<·32)·|·creation.dwLowDateTime |
| 85 | else:··#·pragma:·win32·no·cover | 85 | else:··#·pragma:·win32·no·cover |
| 86 | ····def·process_alive(pid:·int)·->·bool: | 86 | ····def·process_alive(pid:·int)·->·bool: |
| Offset 1, 15 lines modified | Offset 1, 15 lines modified | ||
| 1 | from·__future__·import·annotations | 1 | from·__future__·import·annotations |
| 2 | import·os | 2 | import·os |
| 3 | import·secrets | 3 | import·secrets |
| 4 | import·time | 4 | import·time |
| 5 | from·contextlib·import·suppress | 5 | from·contextlib·import·suppress |
| 6 | from·dataclasses·import·dataclass | 6 | from·dataclasses·import·dataclass |
| 7 | from·threading·import·Event,·Thread,·current_thread | 7 | from·threading·import·Event,·Thread,·current_thread,·local |
| 8 | from·typing·import·TYPE_CHECKING,·Literal | 8 | from·typing·import·TYPE_CHECKING,·Literal |
| 9 | from·._error·import·LeaseSettingsMismatch | 9 | from·._error·import·LeaseSettingsMismatch |
| 10 | from·._identity·import·owner_is_stale | 10 | from·._identity·import·owner_is_stale |
| 11 | from·._marker·import·MarkerSoftFileLock,·OwnerMode,·OwnerRecord,·parse_marker | 11 | from·._marker·import·MarkerSoftFileLock,·OwnerMode,·OwnerRecord,·parse_marker |
| 12 | from·._soft·import·_read_lock_file | 12 | from·._soft·import·_read_lock_file |
| 13 | from·._util·import·break_lock_file,·touch | 13 | from·._util·import·break_lock_file,·touch |
| Offset 36, 14 lines modified | Offset 36, 45 lines modified | ||
| 36 | ····lock_file:·str | 36 | ····lock_file:·str |
| 37 | ····token:·str | 37 | ····token:·str |
| 38 | ····reason:·CompromiseReason | 38 | ····reason:·CompromiseReason |
| 39 | ····error:·OSError·|·None·=·None | 39 | ····error:·OSError·|·None·=·None |
| 40 | @dataclass(frozen=True) | ||
| 41 | class·_Heartbeat: | ||
| 42 | ····"""A·running·heartbeat·and·the·event·that·stops·it,·which·only·ever·exist·together.""" | ||
| 43 | ····thread:·Thread | ||
| 44 | ····stop:·Event | ||
| 45 | @dataclass | ||
| 46 | class·_LeaseClaim: | ||
| 47 | ····"""The·state·of·one·claim:·its·token,·its·heartbeat,·and·how·that·claim·was·lost.""" | ||
| 48 | ····token:·str·|·None·=·None | ||
| 49 | ····compromise:·LeaseCompromise·|·None·=·None | ||
| 50 | ····heartbeat:·_Heartbeat·|·None·=·None | ||
| 51 | class·_LeaseClaimHolder: | ||
| 52 | ····"""Holds·the·claim·its·owning·context·acquired.""" | ||
| 53 | ····#·Only·the·holder·is·thread-local,·mirroring·FileLockContext:·the·claim·stays·an·ordinary·object,·so·the·heartbeat | ||
| 54 | ····#·thread·records·a·compromise·where·the·thread·that·acquired·the·lease·reads·it. | ||
| 55 | ····def·__init__(self)·->·None: | ||
| 56 | ········self.claim·=·_LeaseClaim() | ||
| 57 | class·_ThreadLocalLeaseClaimHolder(_LeaseClaimHolder,·local): | ||
| 58 | ····"""A·thread·local·version·of·the·``_LeaseClaimHolder``·class.""" | ||
| 40 | class·SoftFileLease(MarkerSoftFileLock): | 59 | class·SoftFileLease(MarkerSoftFileLock): |
| 41 | ····""" | 60 | ····""" |
| 42 | ····Existence·lock·whose·claim·expires,·so·a·peer·may·take·it·while·the·previous·holder·still·runs. | 61 | ····Existence·lock·whose·claim·expires,·so·a·peer·may·take·it·while·the·previous·holder·still·runs. |
| 43 | ····A·lease·trades·mutual·exclusion·for·progress.·The·holder·publishes·a·claim·and·refreshes·it·every | 62 | ····A·lease·trades·mutual·exclusion·for·progress.·The·holder·publishes·a·claim·and·refreshes·it·every |
| 44 | ····``heartbeat_interval``·seconds;·a·contender·takes·the·marker·once·it·is·``lease_duration``·seconds·stale.·Nothing | 63 | ····``heartbeat_interval``·seconds;·a·contender·takes·the·marker·once·it·is·``lease_duration``·seconds·stale.·Nothing |
| 45 | ····stops·the·expired·holder:·it·keeps·running,·and·it·keeps·using·whatever·the·lock·protects.·Treat·the·lease·as·a·hint | 64 | ····stops·the·expired·holder:·it·keeps·running,·and·it·keeps·using·whatever·the·lock·protects.·Treat·the·lease·as·a·hint |
| Offset 108, 63 lines modified | Offset 139, 69 lines modified | ||
| 108 | ········if·not·0·<·heartbeat_interval·<·lease_duration: | 139 | ········if·not·0·<·heartbeat_interval·<·lease_duration: |
| 109 | ············msg·=·f"heartbeat_interval·must·be·positive·and·below·lease_duration,·got·{heartbeat_interval!r}" | 140 | ············msg·=·f"heartbeat_interval·must·be·positive·and·below·lease_duration,·got·{heartbeat_interval!r}" |
| 110 | ············raise·ValueError(msg) | 141 | ············raise·ValueError(msg) |
| 111 | ········super().__init__(lock_file,·**kwargs) | 142 | ········super().__init__(lock_file,·**kwargs) |
| 112 | ········self._lease_duration·=·lease_duration | 143 | ········self._lease_duration·=·lease_duration |
| 113 | ········self._heartbeat_interval·=·heartbeat_interval | 144 | ········self._heartbeat_interval·=·heartbeat_interval |
| 114 | ········self._on_compromise·=·on_compromise | 145 | ········self._on_compromise·=·on_compromise |
| 115 | ········self._token:·str·|·None·=·None | ||
| 116 | ········self._compromise:·LeaseCompromise·|·None·=·None | ||
| 117 | ········self._heartbeat_stop·=·Event() | ||
| 118 | ········ | 146 | ········#·Sharing·one·claim·across·a·thread-local·lock·lets·a·second·thread's·failed·acquisition·stop·the·heartbeat·of |
| 147 | ········#·the·thread·holding·the·lease,·leaving·its·marker·unrefreshed·until·a·peer·reclaims·it. | ||
| 148 | ········self._claims:·_LeaseClaimHolder·=·( | ||
| 149 | ············_ThreadLocalLeaseClaimHolder·if·self.is_thread_local()·else·_LeaseClaimHolder | ||
| 150 | ········)() | ||
| 151 | ····@property | ||
| 152 | ····def·_claim(self)·->·_LeaseClaim: | ||
| 153 | ········return·self._claims.claim | ||
| 119 | ····@property | 154 | ····@property |
| 120 | ····def·lease_duration(self)·->·float: | 155 | ····def·lease_duration(self)·->·float: |
| 121 | ········"""The·staleness·in·seconds·after·which·a·contender·may·take·this·claim.""" | 156 | ········"""The·staleness·in·seconds·after·which·a·contender·may·take·this·claim.""" |
| 122 | ········return·self._lease_duration | 157 | ········return·self._lease_duration |
| 123 | ····@property | 158 | ····@property |
| 124 | ····def·token(self)·->·str·|·None: | 159 | ····def·token(self)·->·str·|·None: |
| 125 | ········""" | 160 | ········""" |
| 126 | ········The·token·naming·the·claim·this·process·published. | 161 | ········The·token·naming·the·claim·this·process·published. |
| 127 | ········:returns:·the·token·while·the·lease·is·held,·``None``·otherwise.·It·identifies·a·claim;·it·does·not·fence·one. | 162 | ········:returns:·the·token·while·the·lease·is·held,·``None``·otherwise.·It·identifies·a·claim;·it·does·not·fence·one. |
| 128 | ········""" | 163 | ········""" |
| 129 | ········return·self._token | 164 | ········return·self._claim.token |
| 130 | ····@property | 165 | ····@property |
| 131 | ····def·compromise(self)·->·LeaseCompromise·|·None: | 166 | ····def·compromise(self)·->·LeaseCompromise·|·None: |
| 132 | ········""" | 167 | ········""" |
| 133 | ········The·loss·of·claim·the·heartbeat·observed. | 168 | ········The·loss·of·claim·the·heartbeat·observed. |
| 134 | ········:returns:·the·:class:`LeaseCompromise`,·or·``None``·while·the·claim·still·holds | 169 | ········:returns:·the·:class:`LeaseCompromise`,·or·``None``·while·the·claim·still·holds |
| 135 | ········""" | 170 | ········""" |
| 136 | ········return·self._compromise | 171 | ········return·self._claim.compromise |
| 137 | ····def·_acquire(self)·->·None: | 172 | ····def·_acquire(self)·->·None: |
| 173 | ········claim·=·self._claim | ||
| 138 | ········self._stop_heartbeat()··#·no·earlier·claim's·heartbeat·outlives·the·acquisition·of·the·next·one | 174 | ········self._stop_heartbeat()··#·no·earlier·claim's·heartbeat·outlives·the·acquisition·of·the·next·one |
| 139 | ········ | 175 | ········claim.token·=·token·=·secrets.token_hex(16) |
| 140 | ········ | 176 | ········claim.compromise·=·None |
| 141 | ········super()._acquire() | 177 | ········super()._acquire() |
| 142 | ········#·The·context·is·thread-local·by·default,·so·the·heartbeat·thread·cannot·read·the·descriptor·this·one·just | 178 | ········#·The·context·is·thread-local·by·default,·so·the·heartbeat·thread·cannot·read·the·descriptor·this·one·just |
| 143 | ········#·published.·Hand·it·the·fd | 179 | ········#·published,·nor·the·claim·this·one·owns.·Hand·it·the·fd,·the·inode·it·verified·and·the·claim·instead. |
| 144 | ········if·(fd·:=·self._context.lock_file_fd)·is·not·None·and·( | 180 | ········if·(fd·:=·self._context.lock_file_fd)·is·not·None·and·( |
| 145 | ············identity·:=·self._context.lock_file_fd_identity | 181 | ············identity·:=·self._context.lock_file_fd_identity |
| 146 | ········)·is·not·None: | 182 | ········)·is·not·None: |
| 147 | ············self._start_heartbeat(fd,·identity,· | 183 | ············self._start_heartbeat(claim,·fd,·identity,·token) |
| 148 | ····def·_release(self)·->·None: | 184 | ····def·_release(self)·->·None: |
| 149 | ········self._stop_heartbeat() | 185 | ········self._stop_heartbeat() |
| 150 | ········self._token·=·None | 186 | ········self._claim.token·=·None |
| 151 | ········super()._release() | 187 | ········super()._release() |
| 152 | ····def·_published_record(self)·->·OwnerRecord: | 188 | ····def·_published_record(self)·->·OwnerRecord: |
| 153 | ········return·super()._published_record()._replace(token=self._token,·lease_duration=self._lease_duration) | 189 | ········return·super()._published_record()._replace(token=self._claim.token,·lease_duration=self._lease_duration) |
| Max diff block lines reached; 7018/12377 bytes (56.70%) of diff not shown. | |||
| Offset 57, 16 lines modified | Offset 57, 16 lines modified | ||
| 57 | ········self._lock·=·threading.RLock() | 57 | ········self._lock·=·threading.RLock() |
| 58 | ········self._functions:·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None·=·None | 58 | ········self._functions:·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None·=·None |
| 59 | ····def·functions( | 59 | ····def·functions( |
| 60 | ········self, | 60 | ········self, |
| 61 | ····)·->·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None: | 61 | ····)·->·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None: |
| 62 | ········if·not·_NEEDS_CONNECTION_ESCROW: | 62 | ········if·not·_NEEDS_CONNECTION_ESCROW: |
| 63 | ············return·None | ||
| 64 | ········ | 63 | ············return·None··#·pragma:·>=3.12·cover |
| 64 | ········with·self._lock:··#·pragma:·<3.12·cover··#·pragma:·needs·fork | ||
| 65 | ············if·self._functions·is·None: | 65 | ············if·self._functions·is·None: |
| 66 | ················import·ctypes··#·ruff:ignore[import-outside-top-level]··#·keep·optional·ctypes·and·its·audited·dlsym·out·of·ordinary·imports | 66 | ················import·ctypes··#·ruff:ignore[import-outside-top-level]··#·keep·optional·ctypes·and·its·audited·dlsym·out·of·ordinary·imports |
| 67 | ················function_type·=·ctypes.PYFUNCTYPE(None,·ctypes.py_object) | 67 | ················function_type·=·ctypes.PYFUNCTYPE(None,·ctypes.py_object) |
| 68 | ················increment_address·=·ctypes.cast(ctypes.pythonapi.Py_IncRef,·ctypes.c_void_p).value | 68 | ················increment_address·=·ctypes.cast(ctypes.pythonapi.Py_IncRef,·ctypes.c_void_p).value |
| 69 | ················decrement_address·=·ctypes.cast(ctypes.pythonapi.Py_DecRef,·ctypes.c_void_p).value | 69 | ················decrement_address·=·ctypes.cast(ctypes.pythonapi.Py_DecRef,·ctypes.c_void_p).value |
| 70 | ················if·increment_address·is·None·or·decrement_address·is·None:··#·pragma:·no·cover·-·resolved·CPython·API | 70 | ················if·increment_address·is·None·or·decrement_address·is·None:··#·pragma:·no·cover·-·resolved·CPython·API |
| Offset 74, 15 lines modified | Offset 74, 15 lines modified | ||
| 74 | ····················raise·RuntimeError(msg) | 74 | ····················raise·RuntimeError(msg) |
| 75 | ················self._functions·=·( | 75 | ················self._functions·=·( |
| 76 | ····················cast("Callable[[sqlite3.Connection],·None]",·function_type(increment_address)), | 76 | ····················cast("Callable[[sqlite3.Connection],·None]",·function_type(increment_address)), |
| 77 | ····················cast("Callable[[sqlite3.Connection],·None]",·function_type(decrement_address)), | 77 | ····················cast("Callable[[sqlite3.Connection],·None]",·function_type(decrement_address)), |
| 78 | ················) | 78 | ················) |
| 79 | ············return·self._functions | 79 | ············return·self._functions |
| 80 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:· | 80 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·forked·child |
| 81 | ········self._lock·=·threading.RLock() | 81 | ········self._lock·=·threading.RLock() |
| 82 | _CONNECTION_ESCROW:·Final·=·_ConnectionEscrow() | 82 | _CONNECTION_ESCROW:·Final·=·_ConnectionEscrow() |
| 83 | class·_ForkedDatabaseRegistry: | 83 | class·_ForkedDatabaseRegistry: |
| Offset 96, 15 lines modified | Offset 96, 15 lines modified | ||
| 96 | ····def·raise_if_poisoned(self,·path:·pathlib.Path)·->·None: | 96 | ····def·raise_if_poisoned(self,·path:·pathlib.Path)·->·None: |
| 97 | ········identity·=·self.identity(path) | 97 | ········identity·=·self.identity(path) |
| 98 | ········with·self._lock: | 98 | ········with·self._lock: |
| 99 | ············all_paths_poisoned·=·self._all_paths_poisoned | 99 | ············all_paths_poisoned·=·self._all_paths_poisoned |
| 100 | ············poisoned·=·( | 100 | ············poisoned·=·( |
| 101 | ················all_paths_poisoned·or·path·in·self._paths·or·(identity·is·not·None·and·identity·in·self._identities) | 101 | ················all_paths_poisoned·or·path·in·self._paths·or·(identity·is·not·None·and·identity·in·self._identities) |
| 102 | ············) | 102 | ············) |
| 103 | ········if·poisoned: | 103 | ········if·poisoned:··#·pragma:·needs·fork |
| 104 | ············msg·=·( | 104 | ············msg·=·( |
| 105 | ················"ReadWriteLock·is·unavailable·in·a·PyPy·fork·child;·exec·or·exit·before·using·it" | 105 | ················"ReadWriteLock·is·unavailable·in·a·PyPy·fork·child;·exec·or·exit·before·using·it" |
| 106 | ················if·all_paths_poisoned | 106 | ················if·all_paths_poisoned |
| 107 | ················else·f"SQLite·database·{path!s}·was·active·across·fork();·exec·or·exit·before·using·it·in·the·child" | 107 | ················else·f"SQLite·database·{path!s}·was·active·across·fork();·exec·or·exit·before·using·it·in·the·child" |
| 108 | ············) | 108 | ············) |
| 109 | ············raise·RuntimeError(msg) | 109 | ············raise·RuntimeError(msg) |
| Offset 114, 15 lines modified | Offset 114, 15 lines modified | ||
| 114 | ············self._identities.add(identity) | 114 | ············self._identities.add(identity) |
| 115 | ····def·note_sqlite_use(self)·->·None: | 115 | ····def·note_sqlite_use(self)·->·None: |
| 116 | ········if·_IS_PYPY: | 116 | ········if·_IS_PYPY: |
| 117 | ············with·self._lock: | 117 | ············with·self._lock: |
| 118 | ················self._sqlite_used·=·True | 118 | ················self._sqlite_used·=·True |
| 119 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:· | 119 | ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·forked·child |
| 120 | ········self._lock·=·threading.RLock() | 120 | ········self._lock·=·threading.RLock() |
| 121 | ········self._all_paths_poisoned·=·self._all_paths_poisoned·or·(_IS_PYPY·and·self._sqlite_used) | 121 | ········self._all_paths_poisoned·=·self._all_paths_poisoned·or·(_IS_PYPY·and·self._sqlite_used) |
| 122 | ········self._sqlite_used·=·False | 122 | ········self._sqlite_used·=·False |
| 123 | ····@staticmethod | 123 | ····@staticmethod |
| 124 | ····def·identity(path:·pathlib.Path)·->·_DatabaseIdentity·|·None: | 124 | ····def·identity(path:·pathlib.Path)·->·_DatabaseIdentity·|·None: |
| 125 | ········try: | 125 | ········try: |
| Offset 147, 27 lines modified | Offset 147, 28 lines modified | ||
| 147 | ········connection·=·super().__new__(cls) | 147 | ········connection·=·super().__new__(cls) |
| 148 | ········connection._creator_pid·=·_GETPID() | 148 | ········connection._creator_pid·=·_GETPID() |
| 149 | ········connection._decrement_escrow·=·None | 149 | ········connection._decrement_escrow·=·None |
| 150 | ········return·connection | 150 | ········return·connection |
| 151 | ····def·close(self)·->·None: | 151 | ····def·close(self)·->·None: |
| 152 | ········with·_sqlite_transition(): | 152 | ········with·_sqlite_transition(): |
| 153 | ············if·_GETPID()·!=·self._creator_pid: | 153 | ············if·_GETPID()·!=·self._creator_pid:··#·pragma:·needs·fork |
| 154 | ················return | 154 | ················return |
| 155 | ············with·_fork_transition(): | 155 | ············with·_fork_transition(): |
| 156 | ················sqlite3.Connection.close(self) | 156 | ················sqlite3.Connection.close(self) |
| 157 | ················if·(decrement·:=·self._decrement_escrow)·is·not·None: | 157 | ················if·(decrement·:=·self._decrement_escrow)·is·not·None:··#·pragma:·<3.12·cover··#·pragma:·needs·fork |
| 158 | ····················self._decrement_escrow·=·None | 158 | ····················self._decrement_escrow·=·None |
| 159 | ····················decrement(self) | 159 | ····················decrement(self) |
| 160 | ····def·acquire_escrow( | 160 | ····def·acquire_escrow(··#·pragma:·<3.12·cover··#·pragma:·needs·fork |
| 161 | ········self, | 161 | ········self, |
| 162 | ········functions:·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None, | 162 | ········functions:·tuple[Callable[[sqlite3.Connection],·None],·Callable[[sqlite3.Connection],·None]]·|·None, |
| 163 | ····)·->·None: | 163 | ····)·->·None: |
| 164 | ········#·The·caller·only·reaches·here·holding·the·escrow·functions;·it·skips·the·call·entirely·without·them. | ||
| 164 | ········if·functions·is·not·None: | 165 | ········if·functions·is·not·None:··#·pragma:·no·branch |
| 165 | ············increment,·decrement·=·functions | 166 | ············increment,·decrement·=·functions |
| 166 | ············increment(self) | 167 | ············increment(self) |
| 167 | ············self._decrement_escrow·=·decrement | 168 | ············self._decrement_escrow·=·decrement |
| 168 | ····def·__del__(self)·->·None: | 169 | ····def·__del__(self)·->·None: |
| 169 | ········with·suppress(sqlite3.Error,·RuntimeError): | 170 | ········with·suppress(sqlite3.Error,·RuntimeError): |
| 170 | ············self.close() | 171 | ············self.close() |
| Offset 197, 15 lines modified | Offset 198, 15 lines modified | ||
| 197 | ····)·->·ReadWriteLock: | 198 | ····)·->·ReadWriteLock: |
| 198 | ········_ensure_current_process() | 199 | ········_ensure_current_process() |
| 199 | ········if·cls._instances_pid·!=·_GETPID(): | 200 | ········if·cls._instances_pid·!=·_GETPID(): |
| 200 | ············cls._reset_class_after_fork() | 201 | ············cls._reset_class_after_fork() |
| 201 | ········construction_pid·=·_GETPID() | 202 | ········construction_pid·=·_GETPID() |
| 202 | ········if·not·is_singleton: | 203 | ········if·not·is_singleton: |
| 203 | ············instance·=·super().__call__(lock_file,·timeout,·blocking=blocking,·is_singleton=is_singleton) | 204 | ············instance·=·super().__call__(lock_file,·timeout,·blocking=blocking,·is_singleton=is_singleton) |
| 204 | ············if·_GETPID()·!=·construction_pid:··#·pragma:· | 205 | ············if·_GETPID()·!=·construction_pid:··#·pragma:·forked·child |
| 205 | ················msg·=·"ReadWriteLock·construction·cannot·continue·after·fork" | 206 | ················msg·=·"ReadWriteLock·construction·cannot·continue·after·fork" |
| 206 | ················raise·RuntimeError(msg) | 207 | ················raise·RuntimeError(msg) |
| 207 | ············return·instance | 208 | ············return·instance |
| 208 | ········normalized·=·pathlib.Path(lock_file).resolve() | 209 | ········normalized·=·pathlib.Path(lock_file).resolve() |
| 209 | ········with·cls._instances_lock: | 210 | ········with·cls._instances_lock: |
| 210 | ············if·normalized·not·in·cls._instances: | 211 | ············if·normalized·not·in·cls._instances: |
| Offset 230, 15 lines modified | Offset 231, 15 lines modified | ||
| 230 | ················msg·=·( | 231 | ················msg·=·( |
| 231 | ····················f"Singleton·lock·created·with·timeout={instance.timeout},·blocking={instance.blocking}," | 232 | ····················f"Singleton·lock·created·with·timeout={instance.timeout},·blocking={instance.blocking}," |
| 232 | ····················f"·cannot·be·changed·to·timeout={timeout},·blocking={blocking}" | 233 | ····················f"·cannot·be·changed·to·timeout={timeout},·blocking={blocking}" |
| 233 | ················) | 234 | ················) |
| 234 | ················raise·ValueError(msg) | 235 | ················raise·ValueError(msg) |
| 235 | ············return·instance | 236 | ············return·instance |
| 236 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:· | 237 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·forked·child |
| 237 | ········cls._instances·=·WeakValueDictionary() | 238 | ········cls._instances·=·WeakValueDictionary() |
| 238 | ········cls._instances_lock·=·threading.RLock() | 239 | ········cls._instances_lock·=·threading.RLock() |
| 239 | ········cls._instances_pid·=·_GETPID() | 240 | ········cls._instances_pid·=·_GETPID() |
| 240 | ········cls._instances_under_construction·=·set() | 241 | ········cls._instances_under_construction·=·set() |
| 241 | class·ReadWriteLock(metaclass=_ReadWriteLockMeta): | 242 | class·ReadWriteLock(metaclass=_ReadWriteLockMeta): |
| Offset 413, 29 lines modified | Offset 414, 29 lines modified | ||
| Max diff block lines reached; 6428/12638 bytes (50.86%) of diff not shown. | |||
| Offset 50, 15 lines modified | Offset 50, 15 lines modified | ||
| 50 | ····def·_acquire(self)·->·None: | 50 | ····def·_acquire(self)·->·None: |
| 51 | ········raise_on_not_writable_file(self.lock_file) | 51 | ········raise_on_not_writable_file(self.lock_file) |
| 52 | ········ensure_directory_exists(self.lock_file) | 52 | ········ensure_directory_exists(self.lock_file) |
| 53 | ········#·O_CREAT·|·O_EXCL·makes·the·create·fail·with·EEXIST·when·the·file·already·exists,·so·a·successful·open | 53 | ········#·O_CREAT·|·O_EXCL·makes·the·create·fail·with·EEXIST·when·the·file·already·exists,·so·a·successful·open |
| 54 | ········#·means·this·process·now·holds·the·lock. | 54 | ········#·means·this·process·now·holds·the·lock. |
| 55 | ········flags·=·os.O_WRONLY·|·os.O_CREAT·|·os.O_EXCL·|·os.O_TRUNC | 55 | ········flags·=·os.O_WRONLY·|·os.O_CREAT·|·os.O_EXCL·|·os.O_TRUNC |
| 56 | ········if·(o_nofollow·:=·getattr(os,·"O_NOFOLLOW",·None))·is·not·None: | 56 | ········if·(o_nofollow·:=·getattr(os,·"O_NOFOLLOW",·None))·is·not·None:··#·pragma:·needs·o-nofollow |
| 57 | ············flags·|=·o_nofollow | 57 | ············flags·|=·o_nofollow |
| 58 | ········try: | 58 | ········try: |
| 59 | ············fd·=·os.open(self.lock_file,·flags,·self._open_mode()) | 59 | ············fd·=·os.open(self.lock_file,·flags,·self._open_mode()) |
| 60 | ········except·OSError·as·exception: | 60 | ········except·OSError·as·exception: |
| 61 | ············if·not·( | 61 | ············if·not·( |
| 62 | ················exception.errno·==·EEXIST·or·(exception.errno·==·EACCES·and·sys.platform·==·"win32") | 62 | ················exception.errno·==·EEXIST·or·(exception.errno·==·EACCES·and·sys.platform·==·"win32") |
| 63 | ············):··#·pragma:·win32·no·cover | 63 | ············):··#·pragma:·win32·no·cover |
| Offset 84, 15 lines modified | Offset 84, 15 lines modified | ||
| 84 | ····················Path(self.lock_file).unlink() | 84 | ····················Path(self.lock_file).unlink() |
| 85 | ············raise | 85 | ············raise |
| 86 | ········self._mark_descriptor_owned(fd,·identity) | 86 | ········self._mark_descriptor_owned(fd,·identity) |
| 87 | ····def·_try_break_stale_lock(self)·->·None: | 87 | ····def·_try_break_stale_lock(self)·->·None: |
| 88 | ········with·suppress(OSError,·ValueError): | 88 | ········with·suppress(OSError,·ValueError): |
| 89 | ············content,·mtime,·ino·=·_read_lock_file(self.lock_file) | 89 | ············content,·mtime,·ino·=·_read_lock_file(self.lock_file) |
| 90 | ············if·content·==·STRICT_SOFT_SENTINEL_RECORD: | 90 | ············if·content·==·STRICT_SOFT_SENTINEL_RECORD:··#·pragma:·needs·hard-link |
| 91 | ················return | 91 | ················return |
| 92 | ············holder·=·_parse_lock_holder(content) | 92 | ············holder·=·_parse_lock_holder(content) |
| 93 | ············if·holder·is·None: | 93 | ············if·holder·is·None: |
| 94 | ················#·Unparsable:·wrong·line·count,·a·non-integer·PID·or·start·token,·empty,·oversized·or·not·UTF-8. | 94 | ················#·Unparsable:·wrong·line·count,·a·non-integer·PID·or·start·token,·empty,·oversized·or·not·UTF-8. |
| 95 | ················#·Self-heal·only·once·the·file·is·clearly·not·a·half-written·fresh·lock·(a·peer·between·O_EXCL·and | 95 | ················#·Self-heal·only·once·the·file·is·clearly·not·a·half-written·fresh·lock·(a·peer·between·O_EXCL·and |
| 96 | ················#·_write_lock_info),·so·the·brief·create-then-write·window·is·never·mistaken·for·a·stale·lock. | 96 | ················#·_write_lock_info),·so·the·brief·create-then-write·window·is·never·mistaken·for·a·stale·lock. |
| Offset 173, 22 lines modified | Offset 173, 22 lines modified | ||
| 173 | ················) | 173 | ················) |
| 174 | ············raise | 174 | ············raise |
| 175 | ········self._unlink_held_marker(identity) | 175 | ········self._unlink_held_marker(identity) |
| 176 | ····def·_unlink_held_marker(self,·identity:·tuple[int,·int]·|·None)·->·None: | 176 | ····def·_unlink_held_marker(self,·identity:·tuple[int,·int]·|·None)·->·None: |
| 177 | ········if·identity·is·None: | 177 | ········if·identity·is·None: |
| 178 | ············return | 178 | ············return |
| 179 | ········if·sys.platform·==·"win32": | 179 | ········if·sys.platform·==·"win32":··#·pragma:·win32·cover |
| 180 | ············self._windows_unlink_if_ours(identity) | 180 | ············self._windows_unlink_if_ours(identity) |
| 181 | ········else: | 181 | ········else:··#·pragma:·win32·no·cover |
| 182 | ············with·suppress(OSError): | 182 | ············with·suppress(OSError): |
| 183 | ················if·_file_identity(os.lstat(self.lock_file))·==·identity: | 183 | ················if·_file_identity(os.lstat(self.lock_file))·==·identity: |
| 184 | ····················Path(self.lock_file).unlink() | 184 | ····················Path(self.lock_file).unlink() |
| 185 | ····def·_windows_unlink_if_ours(self,·identity:·tuple[int,·int])·->·None: | 185 | ····def·_windows_unlink_if_ours(self,·identity:·tuple[int,·int])·->·None:··#·pragma:·win32·cover |
| 186 | ········retry_delay·=·0.001 | 186 | ········retry_delay·=·0.001 |
| 187 | ········for·attempt·in·range(_UNLINK_MAX_RETRIES): | 187 | ········for·attempt·in·range(_UNLINK_MAX_RETRIES): |
| 188 | ············#·Windows·doesn't·immediately·release·file·handles·after·close,·causing·EACCES/EPERM·on·unlink.·Recheck | 188 | ············#·Windows·doesn't·immediately·release·file·handles·after·close,·causing·EACCES/EPERM·on·unlink.·Recheck |
| 189 | ············#·identity·each·attempt:·a·failed·unlink·leaves·a·window·for·a·successor·to·replace·the·marker·at·this·path. | 189 | ············#·identity·each·attempt:·a·failed·unlink·leaves·a·window·for·a·successor·to·replace·the·marker·at·this·path. |
| 190 | ············try: | 190 | ············try: |
| 191 | ················if·_file_identity(os.lstat(self.lock_file))·!=·identity: | 191 | ················if·_file_identity(os.lstat(self.lock_file))·!=·identity: |
| 192 | ····················return | 192 | ····················return |
| Offset 211, 15 lines modified | Offset 211, 15 lines modified | ||
| 211 | def·_read_lock_file(path:·str)·->·tuple[str·|·None,·float,·int]: | 211 | def·_read_lock_file(path:·str)·->·tuple[str·|·None,·float,·int]: |
| 212 | ····#·A·legitimate·lock·file·is·always·a·regular·file.·Classify·the·path·with·lstat·first,·so·any·other·node·(symlink, | 212 | ····#·A·legitimate·lock·file·is·always·a·regular·file.·Classify·the·path·with·lstat·first,·so·any·other·node·(symlink, |
| 213 | ····#·FIFO,·socket,·device)·is·reported·as·a·malformed·lock·the·caller·can·evict,·without·an·os.open·that·would·follow | 213 | ····#·FIFO,·socket,·device)·is·reported·as·a·malformed·lock·the·caller·can·evict,·without·an·os.open·that·would·follow |
| 214 | ····#·a·symlink,·stall·on·a·FIFO,·or·fail·on·a·socket·and·leave·acquisition·wedged.·The·mtime·and·inode·still·flow·back | 214 | ····#·a·symlink,·stall·on·a·FIFO,·or·fail·on·a·socket·and·leave·acquisition·wedged.·The·mtime·and·inode·still·flow·back |
| 215 | ····#·for·the·identity-checked·stale·break.·lstat,·not·stat,·so·a·hostile·symlink·is·never·followed·onto·its·target. | 215 | ····#·for·the·identity-checked·stale·break.·lstat,·not·stat,·so·a·hostile·symlink·is·never·followed·onto·its·target. |
| 216 | ····st·=·os.lstat(path) | 216 | ····st·=·os.lstat(path) |
| 217 | ····if·not·stat.S_ISREG(st.st_mode): | 217 | ····if·not·stat.S_ISREG(st.st_mode):··#·pragma:·needs·fifo |
| 218 | ········return·None,·st.st_mtime,·st.st_ino | 218 | ········return·None,·st.st_mtime,·st.st_ino |
| 219 | ····#·Re-check·on·the·opened·handle:·O_NOFOLLOW·refuses·a·symlink·swapped·in·after·the·lstat,·O_NONBLOCK·stops·a·FIFO | 219 | ····#·Re-check·on·the·opened·handle:·O_NOFOLLOW·refuses·a·symlink·swapped·in·after·the·lstat,·O_NONBLOCK·stops·a·FIFO |
| 220 | ····#·swapped·in·from·stalling·the·open,·and·the·fstat·catches·any·other·non-regular·replacement·race·before·we·read. | 220 | ····#·swapped·in·from·stalling·the·open,·and·the·fstat·catches·any·other·non-regular·replacement·race·before·we·read. |
| 221 | ····#·The·capped·read·stops·a·huge·regular·file·(e.g.·one·filled·from·/dev/zero)·from·exhausting·memory. | 221 | ····#·The·capped·read·stops·a·huge·regular·file·(e.g.·one·filled·from·/dev/zero)·from·exhausting·memory. |
| 222 | ····fd·=·os.open(path,·os.O_RDONLY·|·getattr(os,·"O_NOFOLLOW",·0)·|·getattr(os,·"O_NONBLOCK",·0)) | 222 | ····fd·=·os.open(path,·os.O_RDONLY·|·getattr(os,·"O_NOFOLLOW",·0)·|·getattr(os,·"O_NONBLOCK",·0)) |
| 223 | ····try: | 223 | ····try: |
| 224 | ········st·=·os.fstat(fd) | 224 | ········st·=·os.fstat(fd) |
| Offset 1, 18 lines modified | Offset 1, 19 lines modified | ||
| 1 | from·__future__·import·annotations | 1 | from·__future__·import·annotations |
| 2 | import·contextlib | 2 | import·contextlib |
| 3 | import·errno | ||
| 3 | import·os | 4 | import·os |
| 4 | import·secrets | 5 | import·secrets |
| 5 | import·stat | 6 | import·stat |
| 6 | import·sys | 7 | import·sys |
| 7 | import·tempfile | 8 | import·tempfile |
| 8 | import·time | 9 | import·time |
| 9 | from·dataclasses·import·dataclass | 10 | from·dataclasses·import·dataclass |
| 10 | from·errno·import·EACCES,·EEXIST,·ENOENT,·ENOSYS,·E | 11 | from·errno·import·EACCES,·EEXIST,·ENOENT,·ENOSYS,·EPERM,·ESTALE,·EXDEV |
| 11 | from·pathlib·import·Path | 12 | from·pathlib·import·Path |
| 12 | from·typing·import·TYPE_CHECKING,·Final,·Literal,·cast | 13 | from·typing·import·TYPE_CHECKING,·Final,·Literal,·cast |
| 13 | from·._api·import·BaseFileLock,·_canonical,·_raise_cleanup_errors | 14 | from·._api·import·BaseFileLock,·_canonical,·_raise_cleanup_errors |
| 14 | from·._error·import·SoftFileLockProtocolError | 15 | from·._error·import·SoftFileLockProtocolError |
| 15 | from·._identity·import·host_name,·process_start_token | 16 | from·._identity·import·host_name,·process_start_token |
| 16 | from·._soft_protocol·import·STRICT_SOFT_SENTINEL_RECORD | 17 | from·._soft_protocol·import·STRICT_SOFT_SENTINEL_RECORD |
| Offset 74, 14 lines modified | Offset 75, 27 lines modified | ||
| 74 | ········return·False | 75 | ········return·False |
| 75 | ····return·True | 76 | ····return·True |
| 76 | _LINK_HONORS_FOLLOW_SYMLINKS:·Final[bool]·=·_probe_link_follow_symlinks() | 77 | _LINK_HONORS_FOLLOW_SYMLINKS:·Final[bool]·=·_probe_link_follow_symlinks() |
| 78 | def·_probe_hard_link_unsupported_errnos()·->·frozenset[int]: | ||
| 79 | ····#·GraalPy's·errno·omits·ENOTSUP,·so·importing·the·name·outright·breaks·every·runtime·that·ships·without·it.·ENOTSUP | ||
| 80 | ····#·wins·wherever·it·exists,·leaving·every·runtime·that·names·it·unchanged.·EOPNOTSUPP·only·stands·in·for·the·ones | ||
| 81 | ····#·that·do·not,·and·it·approximates·rather·than·matches:·the·two·codes·agree·on·Linux·but·differ·on·macOS/BSD·and·on | ||
| 82 | ····#·Windows.·Where·neither·exists·a·runtime·that·cannot·name·"operation·not·supported"·cannot·raise·it·either,·and | ||
| 83 | ····#·ENOSYS/EXDEV·still·classify·the·link·failures·it·can·raise. | ||
| 84 | ····not_supported·=·getattr(errno,·"ENOTSUP",·getattr(errno,·"EOPNOTSUPP",·None)) | ||
| 85 | ····return·frozenset({ENOSYS,·EXDEV}·if·not_supported·is·None·else·{ENOSYS,·EXDEV,·not_supported}) | ||
| 86 | _HARD_LINK_UNSUPPORTED_ERRNOS:·Final[frozenset[int]]·=·_probe_hard_link_unsupported_errnos() | ||
| 77 | class·StrictSoftFileLock(BaseFileLock): | 87 | class·StrictSoftFileLock(BaseFileLock): |
| 78 | ····"""Portable·fail-closed·lock·based·on·immutable·owner·claims.""" | 88 | ····"""Portable·fail-closed·lock·based·on·immutable·owner·claims.""" |
| 79 | ····_preserve_lock_file_supported:·bool·=·True | 89 | ····_preserve_lock_file_supported:·bool·=·True |
| 80 | ····_on_acquired_supported:·bool·=·False | 90 | ····_on_acquired_supported:·bool·=·False |
| 81 | ····#:·Age·cannot·clear·a·strict·claim:·expiring·one·on·a·clock·is·the·overlap·the·fail-closed·contract·exists·to·rule | 91 | ····#:·Age·cannot·clear·a·strict·claim:·expiring·one·on·a·clock·is·the·overlap·the·fail-closed·contract·exists·to·rule |
| 82 | ····#:·out,·so·only·force_break()·removes·it. | 92 | ····#:·out,·so·only·force_break()·removes·it. |
| Offset 137, 15 lines modified | Offset 151, 15 lines modified | ||
| 137 | ············return | 151 | ············return |
| 138 | ········except·(NotImplementedError,·OSError)·as·error: | 152 | ········except·(NotImplementedError,·OSError)·as·error: |
| 139 | ············_raise_if_hard_links_unsupported(self.lock_file,·error) | 153 | ············_raise_if_hard_links_unsupported(self.lock_file,·error) |
| 140 | ············if·isinstance(error,·OSError)·and·error.errno·==·EEXIST: | 154 | ············if·isinstance(error,·OSError)·and·error.errno·==·EEXIST: |
| 141 | ················self._discard_doorway(sentinel_fd,·sentinel_identity) | 155 | ················self._discard_doorway(sentinel_fd,·sentinel_identity) |
| 142 | ················return | 156 | ················return |
| 143 | ············raise | 157 | ············raise |
| 144 | ········if·publication_cleanup_error·is·not·None: | 158 | ········if·publication_cleanup_error·is·not·None:··#·pragma:·needs·dir-fd |
| 145 | ············raise·publication_cleanup_error | 159 | ············raise·publication_cleanup_error |
| 146 | ········self._context.owner_claim_paths·=·(intent_path,) | 160 | ········self._context.owner_claim_paths·=·(intent_path,) |
| 147 | ········claims·=·_read_existing_claims(self.lock_file,·claim_directory) | 161 | ········claims·=·_read_existing_claims(self.lock_file,·claim_directory) |
| 148 | ········if·( | 162 | ········if·( |
| 149 | ············not·claims | 163 | ············not·claims |
| 150 | ············or·any(claim.state·==·"held"·for·claim·in·claims) | 164 | ············or·any(claim.state·==·"held"·for·claim·in·claims) |
| Offset 158, 15 lines modified | Offset 172, 15 lines modified | ||
| 158 | ········held_path·=·str(claim_directory·/·held_name) | 172 | ········held_path·=·str(claim_directory·/·held_name) |
| 159 | ········try: | 173 | ········try: |
| 160 | ············link_cleanup_error·=·_link_no_replace(claim_directory,·intent_name,·held_name) | 174 | ············link_cleanup_error·=·_link_no_replace(claim_directory,·intent_name,·held_name) |
| 161 | ········except·(NotImplementedError,·OSError)·as·error: | 175 | ········except·(NotImplementedError,·OSError)·as·error: |
| 162 | ············_raise_if_hard_links_unsupported(self.lock_file,·error) | 176 | ············_raise_if_hard_links_unsupported(self.lock_file,·error) |
| 163 | ············raise | 177 | ············raise |
| 164 | ········self._context.owner_claim_paths·=·(held_path,·intent_path) | 178 | ········self._context.owner_claim_paths·=·(held_path,·intent_path) |
| 165 | ········if·link_cleanup_error·is·not·None: | 179 | ········if·link_cleanup_error·is·not·None:··#·pragma:·needs·dir-fd |
| 166 | ············self._context.owner_claim_paths·=·() | 180 | ············self._context.owner_claim_paths·=·() |
| 167 | ············raise·link_cleanup_error | 181 | ············raise·link_cleanup_error |
| 168 | ········claims·=·_read_existing_claims(self.lock_file,·claim_directory) | 182 | ········claims·=·_read_existing_claims(self.lock_file,·claim_directory) |
| 169 | ········if·( | 183 | ········if·( |
| 170 | ············not·{intent_name,·held_name}.issubset(claim.name·for·claim·in·claims) | 184 | ············not·{intent_name,·held_name}.issubset(claim.name·for·claim·in·claims) |
| 171 | ············or·min(_claim_token_key(claim.name)·for·claim·in·claims)·!=·f"v1-{token}.claim" | 185 | ············or·min(_claim_token_key(claim.name)·for·claim·in·claims)·!=·f"v1-{token}.claim" |
| Offset 186, 15 lines modified | Offset 200, 17 lines modified | ||
| 186 | ········"""Published·claims·that·block·acquisition.""" | 200 | ········"""Published·claims·that·block·acquisition.""" |
| 187 | ········return·_read_existing_claims(self.lock_file,·self._claim_directory) | 201 | ········return·_read_existing_claims(self.lock_file,·self._claim_directory) |
| 188 | ····def·force_break(self,·claim_name:·str)·->·None: | 202 | ····def·force_break(self,·claim_name:·str)·->·None: |
| 189 | ········"""Remove·one·named·claim,·allowing·overlap·if·its·owner·still·holds·the·protected·resource.""" | 203 | ········"""Remove·one·named·claim,·allowing·overlap·if·its·owner·still·holds·the·protected·resource.""" |
| 190 | ········_validate_force_break_name(claim_name) | 204 | ········_validate_force_break_name(claim_name) |
| 191 | ········_require_exact_name(self._claim_directory,·claim_name) | 205 | ········_require_exact_name(self._claim_directory,·claim_name) |
| 206 | ········if·( | ||
| 192 | ········ | 207 | ············cleanup_error·:=·_unlink_in_directory(self._claim_directory,·claim_name) |
| 208 | ········)·is·not·None:··#·pragma:·needs·dir-fd | ||
| 193 | ············raise·cleanup_error | 209 | ············raise·cleanup_error |
| 194 | ····def·_rollback_failed_acquire(self,·acquisition_error:·BaseException)·->·None: | 210 | ····def·_rollback_failed_acquire(self,·acquisition_error:·BaseException)·->·None: |
| 195 | ········#·_acquire·already·reconciles·a·failed·doorway·through·_discard_doorway:·it·either·closes·the·pending | 211 | ········#·_acquire·already·reconciles·a·failed·doorway·through·_discard_doorway:·it·either·closes·the·pending |
| 196 | ········#·descriptor·or,·when·a·held·claim·cannot·be·removed,·commits·it·as·owned·so·a·later·release·retries·and | 212 | ········#·descriptor·or,·when·a·held·claim·cannot·be·removed,·commits·it·as·owned·so·a·later·release·retries·and |
| 197 | ········#·raises·the·cleanup·errors.·A·base·rollback·would·release·that·owned·descriptor·again·and·report·each | 213 | ········#·raises·the·cleanup·errors.·A·base·rollback·would·release·that·owned·descriptor·again·and·report·each |
| 198 | ········#·failure·a·second·time,·so·leave·the·reconciled·state·alone. | 214 | ········#·failure·a·second·time,·so·leave·the·reconciled·state·alone. |
| Offset 276, 15 lines modified | Offset 292, 15 lines modified | ||
| 276 | ····except·_PrivateRecordReclaimedError: | 292 | ····except·_PrivateRecordReclaimedError: |
| 277 | ········return·None | 293 | ········return·None |
| 278 | ····except·(NotImplementedError,·OSError)·as·error: | 294 | ····except·(NotImplementedError,·OSError)·as·error: |
| 279 | ········_raise_if_hard_links_unsupported(lock_file,·error) | 295 | ········_raise_if_hard_links_unsupported(lock_file,·error) |
| 280 | ········if·not·isinstance(error,·OSError)·or·error.errno·!=·EEXIST: | 296 | ········if·not·isinstance(error,·OSError)·or·error.errno·!=·EEXIST: |
| 281 | ············raise | 297 | ············raise |
| 282 | ····else: | 298 | ····else: |
| 283 | ········if·publication_cleanup_error·is·not·None: | 299 | ········if·publication_cleanup_error·is·not·None:··#·pragma:·needs·dir-fd |
| 284 | ············raise·publication_cleanup_error | 300 | ············raise·publication_cleanup_error |
| 285 | ····try: | 301 | ····try: |
| 286 | ········return·_open_sentinel(path) | 302 | ········return·_open_sentinel(path) |
| 287 | ····except·OSError: | 303 | ····except·OSError: |
| 288 | ········return·None | 304 | ········return·None |
| Offset 440, 35 lines modified | Offset 456, 35 lines modified | ||
| 440 | ····private_name·=·_private_record_name(public_name) | 456 | ····private_name·=·_private_record_name(public_name) |
| 441 | ····directory_fd·=·_open_directory(directory)·if·_OPEN_SUPPORTS_DIR_FD·else·None | 457 | ····directory_fd·=·_open_directory(directory)·if·_OPEN_SUPPORTS_DIR_FD·else·None |
| 442 | ····directory_ref·=·directory,·directory_fd | 458 | ····directory_ref·=·directory,·directory_fd |
| 443 | ····try: | 459 | ····try: |
| 444 | ········_publish_record_in_directory(directory_ref,·(private_name,·public_name),·mode,·record) | 460 | ········_publish_record_in_directory(directory_ref,·(private_name,·public_name),·mode,·record) |
| 445 | ····except·BaseException·as·publication_error:··#·preserve·publication·and·directory·cleanup·errors | 461 | ····except·BaseException·as·publication_error:··#·preserve·publication·and·directory·cleanup·errors |
| 446 | ········try: | 462 | ········try: |
| 447 | ············if·directory_fd·is·not·None: | 463 | ············if·directory_fd·is·not·None:··#·pragma:·needs·dir-fd |
| 448 | ················os.close(directory_fd) | 464 | ················os.close(directory_fd) |
| 449 | ········except·BaseException·as·close_error:··#·ruff:ignore[blind-except]··#·preserve·publication·and·directory·cleanup·errors | 465 | ········except·BaseException·as·close_error:··#·ruff:ignore[blind-except]··#·pragma:·needs·dir-fd··#·preserve·publication·and·directory·cleanup·errors |
| 450 | ············_raise_cleanup_errors("strict·publication·directory·cleanup·failed",·publication_error,·close_error) | 466 | ············_raise_cleanup_errors("strict·publication·directory·cleanup·failed",·publication_error,·close_error) |
| 451 | ········raise | 467 | ········raise |
| 452 | ····if·directory_fd·is·not·None: | 468 | ····if·directory_fd·is·not·None:··#·pragma:·needs·dir-fd |
| Max diff block lines reached; 8706/15245 bytes (57.11%) of diff not shown. | |||
| Offset 111, 15 lines modified | Offset 111, 15 lines modified | ||
| 111 | def·touch(name:·str,·*,·fd:·int·|·None·=·None)·->·None: | 111 | def·touch(name:·str,·*,·fd:·int·|·None·=·None)·->·None: |
| 112 | ····#·Prefer·the·already-open,·already-verified·fd·so·a·peer·that·swaps·a·symlink·or·a·different·file·in·at·the | 112 | ····#·Prefer·the·already-open,·already-verified·fd·so·a·peer·that·swaps·a·symlink·or·a·different·file·in·at·the |
| 113 | ····#·path·after·our·O_NOFOLLOW·read·cannot·redirect·the·touch:·utime·then·targets·the·inode·behind·the·fd. | 113 | ····#·path·after·our·O_NOFOLLOW·read·cannot·redirect·the·touch:·utime·then·targets·the·inode·behind·the·fd. |
| 114 | ····#·Where·the·platform·cannot·utime·an·fd,·fall·back·to·a·path-based·touch·that·still·refuses·to·follow·a | 114 | ····#·Where·the·platform·cannot·utime·an·fd,·fall·back·to·a·path-based·touch·that·still·refuses·to·follow·a |
| 115 | ····#·symlink·where·supported,·matching·the·O_NOFOLLOW·reads·used·elsewhere·here. | 115 | ····#·symlink·where·supported,·matching·the·O_NOFOLLOW·reads·used·elsewhere·here. |
| 116 | ····if·fd·is·not·None·and·_SUPPORTS_UTIME_FD: | 116 | ····if·fd·is·not·None·and·_SUPPORTS_UTIME_FD:··#·pragma:·needs·utime-fd |
| 117 | ········os.utime(fd,·None) | 117 | ········os.utime(fd,·None) |
| 118 | ········return | 118 | ········return |
| 119 | ····os.utime(name,·None,·follow_symlinks=not·_SUPPORTS_UTIME_NOFOLLOW) | 119 | ····os.utime(name,·None,·follow_symlinks=not·_SUPPORTS_UTIME_NOFOLLOW) |
| 120 | #·Retargeting·os.utime·to·an·open·fd·lets·a·heartbeat·refresh·the·exact·inode·it·verified·instead·of·whatever·the | 120 | #·Retargeting·os.utime·to·an·open·fd·lets·a·heartbeat·refresh·the·exact·inode·it·verified·instead·of·whatever·the |
| 121 | #·pathname·now·names. | 121 | #·pathname·now·names. |
| Offset 154, 19 lines modified | Offset 154, 21 lines modified | ||
| 154 | ········overlapped·=·_OVERLAPPED()··#·zero-initialized,·so·Offset/OffsetHigh/hEvent·are·0 | 154 | ········overlapped·=·_OVERLAPPED()··#·zero-initialized,·so·Offset/OffsetHigh/hEvent·are·0 |
| 155 | ········flags·=·_LOCKFILE_EXCLUSIVE_LOCK·|·_LOCKFILE_FAIL_IMMEDIATELY | 155 | ········flags·=·_LOCKFILE_EXCLUSIVE_LOCK·|·_LOCKFILE_FAIL_IMMEDIATELY |
| 156 | ········if·_kernel32.LockFileEx(msvcrt.get_osfhandle(fd),·flags,·0,·1,·0,·ctypes.byref(overlapped)): | 156 | ········if·_kernel32.LockFileEx(msvcrt.get_osfhandle(fd),·flags,·0,·1,·0,·ctypes.byref(overlapped)): |
| 157 | ············return·True | 157 | ············return·True |
| 158 | ········err·=·ctypes.get_last_error() | 158 | ········err·=·ctypes.get_last_error() |
| 159 | ········if·err·==·_ERROR_LOCK_VIOLATION: | 159 | ········if·err·==·_ERROR_LOCK_VIOLATION: |
| 160 | ············return·False | 160 | ············return·False |
| 161 | ········#·A·non-contention·LockFileEx·failure·is·not·reproducible·in-process. | ||
| 161 | ········raise·ctypes.WinError(err) | 162 | ········raise·ctypes.WinError(err)··#·pragma:·no·cover |
| 162 | ····def·_unlock_fd(fd:·int)·->·None: | 163 | ····def·_unlock_fd(fd:·int)·->·None: |
| 163 | ········overlapped·=·_OVERLAPPED()··#·the·same·offset·0·and·one-byte·length·the·lock·used | 164 | ········overlapped·=·_OVERLAPPED()··#·the·same·offset·0·and·one-byte·length·the·lock·used |
| 165 | ········#·Unlocking·the·exact·range·we·hold·does·not·fail. | ||
| 164 | ········if·not·_kernel32.UnlockFileEx(msvcrt.get_osfhandle(fd),·0,·1,·0,·ctypes.byref(overlapped)): | 166 | ········if·not·_kernel32.UnlockFileEx(msvcrt.get_osfhandle(fd),·0,·1,·0,·ctypes.byref(overlapped)):··#·pragma:·no·cover |
| 165 | ············raise·ctypes.WinError(ctypes.get_last_error()) | 167 | ············raise·ctypes.WinError(ctypes.get_last_error()) |
| 166 | ····class·WindowsFileLock(BaseFileLock): | 168 | ····class·WindowsFileLock(BaseFileLock): |
| 167 | ········""" | 169 | ········""" |
| 168 | ········Uses·``LockFileEx``·to·hard·lock·a·byte·range·of·the·lock·file·on·Windows·systems. | 170 | ········Uses·``LockFileEx``·to·hard·lock·a·byte·range·of·the·lock·file·on·Windows·systems. |
| 169 | ········Lock·file·cleanup:·Windows·attempts·to·delete·the·lock·file·after·release,·but·deletion·is | 171 | ········Lock·file·cleanup:·Windows·attempts·to·delete·the·lock·file·after·release,·but·deletion·is |
| Offset 183, 15 lines modified | Offset 185, 15 lines modified | ||
| 183 | ············fd·=·_open_non_reparse_fd(self.lock_file,·self._open_mode()) | 185 | ············fd·=·_open_non_reparse_fd(self.lock_file,·self._open_mode()) |
| 184 | ············if·fd·is·None: | 186 | ············if·fd·is·None: |
| 185 | ················return··#·open·contention·(share·conflict·or·a·name·pending·deletion);·let·the·retry·loop·try·again | 187 | ················return··#·open·contention·(share·conflict·or·a·name·pending·deletion);·let·the·retry·loop·try·again |
| 186 | ············try: | 188 | ············try: |
| 187 | ················locked·=·_lock_fd_nonblocking(fd) | 189 | ················locked·=·_lock_fd_nonblocking(fd) |
| 188 | ················if·locked: | 190 | ················if·locked: |
| 189 | ····················self._mark_descriptor_owned(fd) | 191 | ····················self._mark_descriptor_owned(fd) |
| 190 | ············except·BaseException: | 192 | ············except·BaseException:··#·pragma:·no·cover··#·cleanup·only·if·the·lock·attempt·itself·raises |
| 191 | ················os.close(fd) | 193 | ················os.close(fd) |
| 192 | ················raise | 194 | ················raise |
| 193 | ············if·not·locked: | 195 | ············if·not·locked: |
| 194 | ················os.close(fd)··#·another·holder·owns·the·byte-range·lock;·let·the·retry·loop·try·again | 196 | ················os.close(fd)··#·another·holder·owns·the·byte-range·lock;·let·the·retry·loop·try·again |
| 195 | ········def·_release(self)·->·None: | 197 | ········def·_release(self)·->·None: |
| 196 | ············fd·=·cast("int",·self._context.lock_file_fd) | 198 | ············fd·=·cast("int",·self._context.lock_file_fd) |
| Offset 242, 27 lines modified | Offset 244, 28 lines modified | ||
| 242 | ········if·status·!=·_STATUS_SUCCESS: | 244 | ········if·status·!=·_STATUS_SUCCESS: |
| 243 | ············if·status·in·{_STATUS_SHARING_VIOLATION,·_STATUS_DELETE_PENDING}: | 245 | ············if·status·in·{_STATUS_SHARING_VIOLATION,·_STATUS_DELETE_PENDING}: |
| 244 | ················return·None | 246 | ················return·None |
| 245 | ············winerror·=·_ntdll.RtlNtStatusToDosError(status) | 247 | ············winerror·=·_ntdll.RtlNtStatusToDosError(status) |
| 246 | ············raise·OSError(None,·ctypes.FormatError(winerror).strip(),·path,·winerror) | 248 | ············raise·OSError(None,·ctypes.FormatError(winerror).strip(),·path,·winerror) |
| 247 | ········info·=·_BY_HANDLE_FILE_INFORMATION() | 249 | ········info·=·_BY_HANDLE_FILE_INFORMATION() |
| 250 | ········#·Querying·an·open·handle·we·just·created·does·not·fail. | ||
| 248 | ········if·not·_kernel32.GetFileInformationByHandle(handle,·ctypes.byref(info)): | 251 | ········if·not·_kernel32.GetFileInformationByHandle(handle,·ctypes.byref(info)):··#·pragma:·no·cover |
| 249 | ············err·=·ctypes.get_last_error() | 252 | ············err·=·ctypes.get_last_error() |
| 250 | ············_kernel32.CloseHandle(handle) | 253 | ············_kernel32.CloseHandle(handle) |
| 251 | ············raise·ctypes.WinError(err) | 254 | ············raise·ctypes.WinError(err) |
| 252 | ········if·info.dwFileAttributes·&·_FILE_ATTRIBUTE_REPARSE_POINT: | 255 | ········if·info.dwFileAttributes·&·_FILE_ATTRIBUTE_REPARSE_POINT: |
| 253 | ············_kernel32.CloseHandle(handle) | 256 | ············_kernel32.CloseHandle(handle) |
| 254 | ············msg·=·f"Lock·file·is·a·reparse·point·(symlink/junction):·{path}" | 257 | ············msg·=·f"Lock·file·is·a·reparse·point·(symlink/junction):·{path}" |
| 255 | ············raise·OSError(msg) | 258 | ············raise·OSError(msg) |
| 256 | ········try: | 259 | ········try: |
| 257 | ············#·O_NOINHERIT·mirrors·os.open·on·Windows:·the·lock·fd·must·not·leak·into·child·processes. | 260 | ············#·O_NOINHERIT·mirrors·os.open·on·Windows:·the·lock·fd·must·not·leak·into·child·processes. |
| 258 | ············return·msvcrt.open_osfhandle(handle,·os.O_RDWR·|·os.O_NOINHERIT) | 261 | ············return·msvcrt.open_osfhandle(handle,·os.O_RDWR·|·os.O_NOINHERIT) |
| 259 | ········except·BaseException:··#·open_osfhandle·audits·too;·a·hook·rais | 262 | ········except·BaseException:··#·pragma:·no·cover··#·open_osfhandle·audits·too;·a·hook·raising·must·not·leak·the·handle |
| 260 | ············_kernel32.CloseHandle(handle) | 263 | ············_kernel32.CloseHandle(handle) |
| 261 | ············raise | 264 | ············raise |
| 262 | ····def·_nt_open(path:·str,·*,·read_only:·bool)·->·tuple[int,·int]: | 265 | ····def·_nt_open(path:·str,·*,·read_only:·bool)·->·tuple[int,·int]: |
| 263 | ········""" | 266 | ········""" |
| 264 | ········Open·*path*·through·``NtCreateFile``·and·return·``(handle,·status)``. | 267 | ········Open·*path*·through·``NtCreateFile``·and·return·``(handle,·status)``. |
| Offset 397, 15 lines modified | Offset 397, 15 lines modified | ||
| 397 | ············if·self.is_locked: | 397 | ············if·self.is_locked: |
| 398 | ················try: | 398 | ················try: |
| 399 | ····················await·_drain_future(self._start_tracked_release()) | 399 | ····················await·_drain_future(self._start_tracked_release()) |
| 400 | ················except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | 400 | ················except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below |
| 401 | ····················rollback_error·=·error | 401 | ····················rollback_error·=·error |
| 402 | ············if·acquire_error·is·not·None: | 402 | ············if·acquire_error·is·not·None: |
| 403 | ················if·rollback_error·is·not·None: | 403 | ················if·rollback_error·is·not·None:··#·pragma:·needs·fcntl |
| 404 | ····················self._raise_cancelled_errors( | 404 | ····················self._raise_cancelled_errors( |
| 405 | ························"lock·acquisition·cancellation,·backend·attempt,·and·rollback·failed", | 405 | ························"lock·acquisition·cancellation,·backend·attempt,·and·rollback·failed", |
| 406 | ························cancellation, | 406 | ························cancellation, |
| 407 | ························acquire_error, | 407 | ························acquire_error, |
| 408 | ························rollback_error, | 408 | ························rollback_error, |
| 409 | ····················) | 409 | ····················) |
| 410 | ················self._raise_cancelled_errors( | 410 | ················self._raise_cancelled_errors( |
| Offset 664, 22 lines modified | Offset 664, 23 lines modified | ||
| 664 | ················errors·:=·_grouped_errors( | 664 | ················errors·:=·_grouped_errors( |
| 665 | ····················release_error, | 665 | ····················release_error, |
| 666 | ····················_ASYNC_RELEASE_CANCELLATION_ERRORS, | 666 | ····················_ASYNC_RELEASE_CANCELLATION_ERRORS, |
| 667 | ····················(_ASYNC_RELEASE_CANCELLATION_MARKER_ATTR,·_ASYNC_RELEASE_CANCELLATION_MARKER), | 667 | ····················(_ASYNC_RELEASE_CANCELLATION_MARKER_ATTR,·_ASYNC_RELEASE_CANCELLATION_MARKER), |
| 668 | ················) | 668 | ················) |
| 669 | ············)·is·not·None: | 669 | ············)·is·not·None: |
| 670 | ················match·errors: | 670 | ················match·errors: |
| 671 | ····················#·The·marker·is·only·ever·set·on·a·(CancelledError,·backend_error)·pair,·so·this·always·matches. | ||
| 671 | ····················case·(asyncio.CancelledError()·as·cancellation,·backend_error): | 672 | ····················case·(asyncio.CancelledError()·as·cancellation,·backend_error):··#·pragma:·no·branch |
| 672 | ························_raise_grouped_errors(_ASYNC_CONTEXT_RELEASE_ERRORS,·body_error,·cancellation,·backend_error) | 673 | ························_raise_grouped_errors(_ASYNC_CONTEXT_RELEASE_ERRORS,·body_error,·cancellation,·backend_error) |
| 673 | ············_raise_body_and_release(body_error,·release_error) | 674 | ············_raise_body_and_release(body_error,·release_error) |
| 674 | ····def·__del__(self)·->·None: | 675 | ····def·__del__(self)·->·None: |
| 675 | ········"""Release·on·deletion;·safe·to·call·during·GC·even·when·no·event·loop·is·running.""" | 676 | ········"""Release·on·deletion;·safe·to·call·during·GC·even·when·no·event·loop·is·running.""" |
| 676 | ········if·vars(self).get("_creator_pid")·!=·os.getpid(): | 677 | ········if·vars(self).get("_creator_pid")·!=·os.getpid(): |
| 677 | ············return··#·pragma:· | 678 | ············return··#·pragma:·forked·child |
| 678 | ········with·contextlib.suppress(Exception): | 679 | ········with·contextlib.suppress(Exception): |
| 679 | ············try: | 680 | ············try: |
| 680 | ················loop·=·asyncio.get_running_loop() | 681 | ················loop·=·asyncio.get_running_loop() |
| 681 | ············except·RuntimeError: | 682 | ············except·RuntimeError: |
| 682 | ················loop·=·self._context.loop·if·self._context.loop·and·not·self._context.loop.is_closed()·else·None | 683 | ················loop·=·self._context.loop·if·self._context.loop·and·not·self._context.loop.is_closed()·else·None |
| 683 | ············if·loop·is·None: | 684 | ············if·loop·is·None: |
| 684 | ················return | 685 | ················return |
| Offset 14, 11 lines modified | Offset 14, 11 lines modified | ||
| 14 | version:·str | 14 | version:·str |
| 15 | __version__:·str | 15 | __version__:·str |
| 16 | __version_tuple__:·tuple[int·|·str,·...] | 16 | __version_tuple__:·tuple[int·|·str,·...] |
| 17 | version_tuple:·tuple[int·|·str,·...] | 17 | version_tuple:·tuple[int·|·str,·...] |
| 18 | commit_id:·str·|·None | 18 | commit_id:·str·|·None |
| 19 | __commit_id__:·str·|·None | 19 | __commit_id__:·str·|·None |
| 20 | __version__·=·version·=·'3.3 | 20 | __version__·=·version·=·'3.32.2' |
| 21 | __version_tuple__·=·version_tuple·=·(3,·3 | 21 | __version_tuple__·=·version_tuple·=·(3,·32,·2) |
| 22 | __commit_id__·=·commit_id·=·None | 22 | __commit_id__·=·commit_id·=·None |
| Offset 4, 21 lines modified | Offset 4, 32 lines modified | ||
| 4 | import·asyncio | 4 | import·asyncio |
| 5 | import·functools | 5 | import·functools |
| 6 | import·os | 6 | import·os |
| 7 | from·contextlib·import·asynccontextmanager | 7 | from·contextlib·import·asynccontextmanager |
| 8 | from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar | 8 | from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar |
| 9 | from·filelock._async·import·( | ||
| 10 | ····_BackendOutcome, | ||
| 11 | ····_capture_call, | ||
| 12 | ····_drain_future, | ||
| 13 | ····_future_result, | ||
| 14 | ····_raise_cancelled_error, | ||
| 15 | ····_wait_until_done, | ||
| 16 | ) | ||
| 9 | from·._sync·import·SoftReadWriteLock | 17 | from·._sync·import·SoftReadWriteLock |
| 10 | if·TYPE_CHECKING: | 18 | if·TYPE_CHECKING: |
| 11 | ····from·collections.abc·import·AsyncGenerator,·Callable | 19 | ····from·collections.abc·import·AsyncGenerator,·Callable |
| 12 | ····from·concurrent·import·futures | 20 | ····from·concurrent·import·futures |
| 13 | ····from·types·import·TracebackType | 21 | ····from·types·import·TracebackType |
| 22 | ····from·filelock._api·import·AcquireReturnProxy | ||
| 14 | _P·=·ParamSpec("_P") | 23 | _P·=·ParamSpec("_P") |
| 15 | _R·=·TypeVar("_R") | 24 | _R·=·TypeVar("_R") |
| 16 | class·AsyncSoftReadWriteLock: | 25 | class·AsyncSoftReadWriteLock: |
| 17 | ····""" | 26 | ····""" |
| 18 | ····Async·wrapper·around·:class:`SoftReadWriteLock`·for·``asyncio``·applications. | 27 | ····Async·wrapper·around·:class:`SoftReadWriteLock`·for·``asyncio``·applications. |
| Offset 144, 15 lines modified | Offset 155, 15 lines modified | ||
| 144 | ········:raises·RuntimeError:·if·a·write·lock·is·already·held,·if·this·instance·was·invalidated·by | 155 | ········:raises·RuntimeError:·if·a·write·lock·is·already·held,·if·this·instance·was·invalidated·by |
| 145 | ············:func:`os.fork`,·or·if·:meth:`close`·was·called | 156 | ············:func:`os.fork`,·or·if·:meth:`close`·was·called |
| 146 | ········:raises·Timeout:·if·the·lock·cannot·be·acquired·within·*timeout*·seconds | 157 | ········:raises·Timeout:·if·the·lock·cannot·be·acquired·within·*timeout*·seconds |
| 147 | ········""" | 158 | ········""" |
| 148 | ········self._raise_if_inherited() | 159 | ········self._raise_if_inherited() |
| 149 | ········await·self._run(self._lock.acquire_read,·timeout,·blocking=blocking) | 160 | ········await·self._run_acquire(functools.partial(self._lock.acquire_read,·timeout,·blocking=blocking)) |
| 150 | ········return·AsyncAcquireSoftReadWriteReturnProxy(lock=self) | 161 | ········return·AsyncAcquireSoftReadWriteReturnProxy(lock=self) |
| 151 | ····async·def·acquire_write( | 162 | ····async·def·acquire_write( |
| 152 | ········self,·timeout:·float·|·None·=·None,·*,·blocking:·bool·|·None·=·None | 163 | ········self,·timeout:·float·|·None·=·None,·*,·blocking:·bool·|·None·=·None |
| 153 | ····)·->·AsyncAcquireSoftReadWriteReturnProxy: | 164 | ····)·->·AsyncAcquireSoftReadWriteReturnProxy: |
| 154 | ········""" | 165 | ········""" |
| 155 | ········Acquire·an·exclusive·write·lock. | 166 | ········Acquire·an·exclusive·write·lock. |
| Offset 167, 15 lines modified | Offset 178, 15 lines modified | ||
| 167 | ········:raises·RuntimeError:·if·a·read·lock·is·already·held,·if·a·write·lock·is·held·by·a·different·thread,·if | 178 | ········:raises·RuntimeError:·if·a·read·lock·is·already·held,·if·a·write·lock·is·held·by·a·different·thread,·if |
| 168 | ············this·instance·was·invalidated·by·:func:`os.fork`,·or·if·:meth:`close`·was·called | 179 | ············this·instance·was·invalidated·by·:func:`os.fork`,·or·if·:meth:`close`·was·called |
| 169 | ········:raises·Timeout:·if·the·lock·cannot·be·acquired·within·*timeout*·seconds | 180 | ········:raises·Timeout:·if·the·lock·cannot·be·acquired·within·*timeout*·seconds |
| 170 | ········""" | 181 | ········""" |
| 171 | ········self._raise_if_inherited() | 182 | ········self._raise_if_inherited() |
| 172 | ········await·self._run(self._lock.acquire_write,·timeout,·blocking=blocking) | 183 | ········await·self._run_acquire(functools.partial(self._lock.acquire_write,·timeout,·blocking=blocking)) |
| 173 | ········return·AsyncAcquireSoftReadWriteReturnProxy(lock=self) | 184 | ········return·AsyncAcquireSoftReadWriteReturnProxy(lock=self) |
| 174 | ····async·def·release(self,·*,·force:·bool·=·False)·->·None: | 185 | ····async·def·release(self,·*,·force:·bool·=·False)·->·None: |
| 175 | ········""" | 186 | ········""" |
| 176 | ········Release·one·level·of·the·current·lock. | 187 | ········Release·one·level·of·the·current·lock. |
| 177 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level | 188 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level |
| Offset 188, 21 lines modified | Offset 199, 57 lines modified | ||
| 188 | ····async·def·close(self)·->·None: | 199 | ····async·def·close(self)·->·None: |
| 189 | ········"""Release·any·held·lock·and·release·the·underlying·filesystem·resources.·Idempotent.""" | 200 | ········"""Release·any·held·lock·and·release·the·underlying·filesystem·resources.·Idempotent.""" |
| 190 | ········if·self._creator_pid·==·os.getpid(): | 201 | ········if·self._creator_pid·==·os.getpid(): |
| 191 | ············await·self._run(self._lock.close) | 202 | ············await·self._run(self._lock.close) |
| 192 | ····def·_raise_if_inherited(self)·->·None: | 203 | ····def·_raise_if_inherited(self)·->·None: |
| 193 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:· | 204 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child |
| 194 | ············msg·=·f"AsyncSoftReadWriteLock·on·{self.lock_file}·was·inherited·across·fork;·construct·a·new·instance" | 205 | ············msg·=·f"AsyncSoftReadWriteLock·on·{self.lock_file}·was·inherited·across·fork;·construct·a·new·instance" |
| 195 | ············raise·RuntimeError(msg) | 206 | ············raise·RuntimeError(msg) |
| 207 | ····async·def·_run_acquire(self,·acquire:·Callable[[],·AcquireReturnProxy])·->·None: | ||
| 208 | ········#·run_in_executor·cannot·recall·work·the·pool·already·started,·so·canceling·the·caller·does·not·stop·the·sync | ||
| 209 | ········#·acquire:·it·still·creates·its·marker,·sets·the·hold,·and·starts·the·heartbeat,·which·keeps·the·marker·fresh | ||
| 210 | ········#·forever·so·no·peer·on·any·host·can·evict·it·as·stale.·Wait·the·submitted·call·out·and·hand·the·claim·back, | ||
| 211 | ········#·the·way·AsyncReadWriteLock·does. | ||
| 212 | ········acquire_future·=·self._submit(acquire) | ||
| 213 | ········try: | ||
| 214 | ············await·_wait_until_done(acquire_future) | ||
| 215 | ········except·asyncio.CancelledError·as·cancellation: | ||
| 216 | ············try: | ||
| 217 | ················await·_drain_future(acquire_future) | ||
| 218 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | ||
| 219 | ················_raise_cancelled_error(cancellation,·error) | ||
| 220 | ············try: | ||
| 221 | ················await·_drain_future(self._submit(self._lock.release)) | ||
| 222 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | ||
| 223 | ················_raise_cancelled_error(cancellation,·error) | ||
| 224 | ············raise | ||
| 225 | ········_future_result(acquire_future) | ||
| 196 | ····async·def·_run(self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs)·->·_R: | 226 | ····async·def·_run(self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs)·->·_R: |
| 227 | ········#·A·canceled·release·or·close·is·already·running·on·the·pool·thread;·drain·it·so·its·outcome·is·observed | ||
| 228 | ········#·instead·of·finishing·unwatched,·then·let·the·cancellation·through. | ||
| 229 | ········future·=·self._submit(func,·*args,·**kwargs) | ||
| 230 | ········try: | ||
| 231 | ············await·_wait_until_done(future) | ||
| 232 | ········except·asyncio.CancelledError·as·cancellation: | ||
| 233 | ············try: | ||
| 234 | ················await·_drain_future(future) | ||
| 235 | ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below | ||
| 236 | ················_raise_cancelled_error(cancellation,·error) | ||
| 237 | ············raise | ||
| 238 | ········return·_future_result(future) | ||
| 239 | ····def·_submit( | ||
| 240 | ········self,·func:·Callable[_P,·_R],·*args:·_P.args,·**kwargs:·_P.kwargs | ||
| 241 | ····)·->·asyncio.Future[_BackendOutcome[_R]]: | ||
| 197 | ········loop·=·self._loop·or·asyncio.get_running_loop() | 242 | ········loop·=·self._loop·or·asyncio.get_running_loop() |
| 198 | ········return· | 243 | ········return·loop.run_in_executor(self._executor,·_capture_call,·functools.partial(func,·*args,·**kwargs)) |
| 199 | class·AsyncAcquireSoftReadWriteReturnProxy: | 244 | class·AsyncAcquireSoftReadWriteReturnProxy: |
| 200 | ····"""Async·context-aware·object·that·releases·an·:class:`AsyncSoftReadWriteLock`·on·exit.""" | 245 | ····"""Async·context-aware·object·that·releases·an·:class:`AsyncSoftReadWriteLock`·on·exit.""" |
| 201 | ····def·__init__(self,·lock:·AsyncSoftReadWriteLock)·->·None: | 246 | ····def·__init__(self,·lock:·AsyncSoftReadWriteLock)·->·None: |
| 202 | ········self.lock·=·lock | 247 | ········self.lock·=·lock |
| Offset 9, 15 lines modified | Offset 9, 15 lines modified | ||
| 9 | import·secrets | 9 | import·secrets |
| 10 | import·socket | 10 | import·socket |
| 11 | import·stat | 11 | import·stat |
| 12 | import·sys | 12 | import·sys |
| 13 | import·threading | 13 | import·threading |
| 14 | import·time | 14 | import·time |
| 15 | import·uuid | 15 | import·uuid |
| 16 | from·contextlib·import·contextmanager,·suppress | 16 | from·contextlib·import·closing,·contextmanager,·suppress |
| 17 | from·dataclasses·import·dataclass | 17 | from·dataclasses·import·dataclass |
| 18 | from·pathlib·import·Path | 18 | from·pathlib·import·Path |
| 19 | from·typing·import·TYPE_CHECKING,·Final,·Literal | 19 | from·typing·import·TYPE_CHECKING,·Final,·Literal |
| 20 | from·weakref·import·WeakValueDictionary | 20 | from·weakref·import·WeakValueDictionary |
| 21 | from·filelock._api·import·( | 21 | from·filelock._api·import·( |
| 22 | ····AcquireReturnProxy, | 22 | ····AcquireReturnProxy, |
| Offset 78, 15 lines modified | Offset 78, 15 lines modified | ||
| 78 | ················poll_interval=poll_interval, | 78 | ················poll_interval=poll_interval, |
| 79 | ············) | 79 | ············) |
| 80 | ········normalized·=·Path(lock_file).resolve() | 80 | ········normalized·=·Path(lock_file).resolve() |
| 81 | ········with·cls._instances_lock: | 81 | ········with·cls._instances_lock: |
| 82 | ············instance·=·cls._instances.get(normalized) | 82 | ············instance·=·cls._instances.get(normalized) |
| 83 | ············if·instance·is·None: | 83 | ············if·instance·is·None: |
| 84 | ················if·normalized·in·_SINGLETONS_UNDER_CONSTRUCTION: | 84 | ················if·normalized·in·_SINGLETONS_UNDER_CONSTRUCTION:··#·pragma:·needs·fork |
| 85 | ····················msg·=·f"Singleton·lock·construction·is·already·active·for·{lock_file!s}" | 85 | ····················msg·=·f"Singleton·lock·construction·is·already·active·for·{lock_file!s}" |
| 86 | ····················raise·RuntimeError(msg) | 86 | ····················raise·RuntimeError(msg) |
| 87 | ················construction_pid·=·os.getpid() | 87 | ················construction_pid·=·os.getpid() |
| 88 | ················_SINGLETONS_UNDER_CONSTRUCTION.add(normalized) | 88 | ················_SINGLETONS_UNDER_CONSTRUCTION.add(normalized) |
| 89 | ················try: | 89 | ················try: |
| 90 | ····················instance·=·super().__call__( | 90 | ····················instance·=·super().__call__( |
| 91 | ························lock_file, | 91 | ························lock_file, |
| Offset 95, 15 lines modified | Offset 95, 15 lines modified | ||
| 95 | ························is_singleton=is_singleton, | 95 | ························is_singleton=is_singleton, |
| 96 | ························heartbeat_interval=heartbeat_interval, | 96 | ························heartbeat_interval=heartbeat_interval, |
| 97 | ························stale_threshold=stale_threshold, | 97 | ························stale_threshold=stale_threshold, |
| 98 | ························poll_interval=poll_interval, | 98 | ························poll_interval=poll_interval, |
| 99 | ····················) | 99 | ····················) |
| 100 | ················finally: | 100 | ················finally: |
| 101 | ····················_SINGLETONS_UNDER_CONSTRUCTION.discard(normalized) | 101 | ····················_SINGLETONS_UNDER_CONSTRUCTION.discard(normalized) |
| 102 | ················if·os.getpid()·!=·construction_pid: | 102 | ················if·os.getpid()·!=·construction_pid:··#·pragma:·needs·fork |
| 103 | ····················msg·=·"Lock·construction·cannot·continue·after·fork;·construct·a·new·lock·in·the·child" | 103 | ····················msg·=·"Lock·construction·cannot·continue·after·fork;·construct·a·new·lock·in·the·child" |
| 104 | ····················raise·RuntimeError(msg) | 104 | ····················raise·RuntimeError(msg) |
| 105 | ················cls._instances[normalized]·=·instance | 105 | ················cls._instances[normalized]·=·instance |
| 106 | ············elif·instance.timeout·!=·timeout·or·instance.blocking·!=·blocking: | 106 | ············elif·instance.timeout·!=·timeout·or·instance.blocking·!=·blocking: |
| 107 | ················msg·=·( | 107 | ················msg·=·( |
| 108 | ····················f"Singleton·lock·created·with·timeout={instance.timeout},·blocking={instance.blocking}," | 108 | ····················f"Singleton·lock·created·with·timeout={instance.timeout},·blocking={instance.blocking}," |
| 109 | ····················f"·cannot·be·changed·to·timeout={timeout},·blocking={blocking}" | 109 | ····················f"·cannot·be·changed·to·timeout={timeout},·blocking={blocking}" |
| Offset 209, 15 lines modified | Offset 209, 15 lines modified | ||
| 209 | ········self._closed:·bool·=·False | 209 | ········self._closed:·bool·=·False |
| 210 | ········with·_ALL_INSTANCES_LOCK: | 210 | ········with·_ALL_INSTANCES_LOCK: |
| 211 | ············_ALL_INSTANCES[id(self)]·=·self | 211 | ············_ALL_INSTANCES[id(self)]·=·self |
| 212 | ········_register_fork_object(self) | 212 | ········_register_fork_object(self) |
| 213 | ····@classmethod | 213 | ····@classmethod |
| 214 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:· | 214 | ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·forked·child |
| 215 | ········global·_ALL_INSTANCES_LOCK··#·ruff:ignore[global-statement]··#·rebinds·the·module·lock·to·a·fresh·one·in·the·fork·child | 215 | ········global·_ALL_INSTANCES_LOCK··#·ruff:ignore[global-statement]··#·rebinds·the·module·lock·to·a·fresh·one·in·the·fork·child |
| 216 | ········_ALL_INSTANCES_LOCK·=·threading.Lock() | 216 | ········_ALL_INSTANCES_LOCK·=·threading.Lock() |
| 217 | ········cls._instances·=·WeakValueDictionary() | 217 | ········cls._instances·=·WeakValueDictionary() |
| 218 | ········cls._instances_lock·=·threading.RLock() | 218 | ········cls._instances_lock·=·threading.RLock() |
| 219 | ········_SINGLETONS_UNDER_CONSTRUCTION.clear() | 219 | ········_SINGLETONS_UNDER_CONSTRUCTION.clear() |
| 220 | ····@contextmanager | 220 | ····@contextmanager |
| Offset 335, 28 lines modified | Offset 335, 28 lines modified | ||
| 335 | ····def·close(self)·->·None: | 335 | ····def·close(self)·->·None: |
| 336 | ········""" | 336 | ········""" |
| 337 | ········Release·any·held·lock·and·release·internal·filesystem·resources. | 337 | ········Release·any·held·lock·and·release·internal·filesystem·resources. |
| 338 | ········Idempotent.·After·calling·this·method·the·instance·can·no·longer·acquire·locks·—·subsequent·acquires·raise | 338 | ········Idempotent.·After·calling·this·method·the·instance·can·no·longer·acquire·locks·—·subsequent·acquires·raise |
| 339 | ········:class:`RuntimeError`.·A·fork-invalidated·instance·is·closed·without·raising. | 339 | ········:class:`RuntimeError`.·A·fork-invalidated·instance·is·closed·without·raising. |
| 340 | ········""" | 340 | ········""" |
| 341 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:· | 341 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child |
| 342 | ············return | 342 | ············return |
| 343 | ········self.release(force=True) | 343 | ········self.release(force=True) |
| 344 | ········with·self._locks.internal: | 344 | ········with·self._locks.internal: |
| 345 | ············if·self._closed: | 345 | ············if·self._closed: |
| 346 | ················return | 346 | ················return |
| 347 | ············self._closed·=·True | 347 | ············self._closed·=·True |
| 348 | ············if·self._readers_dir_fd·is·not·None: | 348 | ············if·self._readers_dir_fd·is·not·None:··#·pragma:·needs·dir-fd |
| 349 | ················with·_fork_transition(): | 349 | ················with·_fork_transition(): |
| 350 | ····················if·self._readers_dir_fd_token·is·not·None: | 350 | ····················if·self._readers_dir_fd_token·is·not·None:··#·pragma:·needs·dir-fd |
| 351 | ························_unregister_owned_descriptor(self._readers_dir_fd_token) | 351 | ························_unregister_owned_descriptor(self._readers_dir_fd_token) |
| 352 | ····················self._readers_dir_fd_token·=·None | 352 | ····················self._readers_dir_fd_token·=·None |
| 353 | ····················fd,·self._readers_dir_fd·=·self._readers_dir_fd,·None | 353 | ····················fd,·self._readers_dir_fd·=·self._readers_dir_fd,·None |
| 354 | ····················with·suppress(OSError): | 354 | ····················with·suppress(OSError):··#·pragma:·needs·dir-fd |
| 355 | ························os.close(fd) | 355 | ························os.close(fd) |
| 356 | ····def·release(self,·*,·force:·bool·=·False)·->·None: | 356 | ····def·release(self,·*,·force:·bool·=·False)·->·None: |
| 357 | ········""" | 357 | ········""" |
| 358 | ········Release·one·level·of·the·current·lock. | 358 | ········Release·one·level·of·the·current·lock. |
| 359 | ········When·the·lock·level·reaches·zero·the·heartbeat·thread·is·stopped·and·the·held·marker·file·is·unlinked.·On·a | 359 | ········When·the·lock·level·reaches·zero·the·heartbeat·thread·is·stopped·and·the·held·marker·file·is·unlinked.·On·a |
| Offset 364, 15 lines modified | Offset 364, 15 lines modified | ||
| 364 | ········this·method·is·a·no-op·so·inherited·``with``·blocks·can·unwind·cleanly·in·the·child. | 364 | ········this·method·is·a·no-op·so·inherited·``with``·blocks·can·unwind·cleanly·in·the·child. |
| 365 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level | 365 | ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level |
| 366 | ········:raises·RuntimeError:·if·no·lock·is·currently·held·and·*force*·is·``False`` | 366 | ········:raises·RuntimeError:·if·no·lock·is·currently·held·and·*force*·is·``False`` |
| 367 | ········""" | 367 | ········""" |
| 368 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:· | 368 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child |
| 369 | ············return | 369 | ············return |
| 370 | ········with·self._locks.internal: | 370 | ········with·self._locks.internal: |
| 371 | ············hold·=·self._hold | 371 | ············hold·=·self._hold |
| 372 | ············if·hold·is·None: | 372 | ············if·hold·is·None: |
| 373 | ················if·force: | 373 | ················if·force: |
| 374 | ····················return | 374 | ····················return |
| 375 | ················msg·=·f"Cannot·release·a·lock·on·{self.lock_file}·(lock·id:·{id(self)})·that·is·not·held" | 375 | ················msg·=·f"Cannot·release·a·lock·on·{self.lock_file}·(lock·id:·{id(self)})·that·is·not·held" |
| Offset 412, 15 lines modified | Offset 412, 15 lines modified | ||
| 412 | ····def·_acquire( | 412 | ····def·_acquire( |
| 413 | ········self, | 413 | ········self, |
| 414 | ········mode:·_Mode, | 414 | ········mode:·_Mode, |
| 415 | ········timeout:·float·|·None, | 415 | ········timeout:·float·|·None, |
| 416 | ········*, | 416 | ········*, |
| 417 | ········blocking:·bool·|·None, | 417 | ········blocking:·bool·|·None, |
| 418 | ····)·->·AcquireReturnProxy: | 418 | ····)·->·AcquireReturnProxy: |
| 419 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:· | 419 | ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child |
| 420 | ············msg·=·f"SoftReadWriteLock·on·{self.lock_file}·was·invalidated·by·fork();·construct·a·new·instance" | 420 | ············msg·=·f"SoftReadWriteLock·on·{self.lock_file}·was·invalidated·by·fork();·construct·a·new·instance" |
| 421 | ············raise·RuntimeError(msg) | 421 | ············raise·RuntimeError(msg) |
| 422 | ········timeout·=·self.timeout·if·timeout·is·None·else·timeout | 422 | ········timeout·=·self.timeout·if·timeout·is·None·else·timeout |
| 423 | ········blocking·=·self.blocking·if·blocking·is·None·else·blocking | 423 | ········blocking·=·self.blocking·if·blocking·is·None·else·blocking |
| 424 | ········with·self._locks.internal: | 424 | ········with·self._locks.internal: |
| 425 | ············if·self._closed: | 425 | ············if·self._closed: |
| Offset 463, 26 lines modified | Offset 463, 41 lines modified | ||
| 463 | ········stop_event·=·threading.Event() | 463 | ········stop_event·=·threading.Event() |
| 464 | ········heartbeat·=·_HeartbeatThread( | 464 | ········heartbeat·=·_HeartbeatThread( |
| Max diff block lines reached; 10219/16376 bytes (62.40%) of diff not shown. | |||
| Offset 189, 9 lines modified | Offset 189, 9 lines modified | ||
| 189 | ····#·Handle·post | 189 | ····#·Handle·post |
| 190 | ····post·=·int(m.group('post'))·if·m.group('post')·else·0 | 190 | ····post·=·int(m.group('post'))·if·m.group('post')·else·0 |
| 191 | ····return·Version(major,·minor,·micro,·release,·pre,·post,·dev) | 191 | ····return·Version(major,·minor,·micro,·release,·pre,·post,·dev) |
| 192 | __version_info__·=·Version(2,·9,· | 192 | __version_info__·=·Version(2,·9,·2,·"final") |
| 193 | __version__·=·__version_info__._get_canonical() | 193 | __version__·=·__version_info__._get_canonical() |
| Offset 183, 14 lines modified | Offset 183, 16 lines modified | ||
| 183 | #·Whitespace·checks | 183 | #·Whitespace·checks |
| 184 | RE_WS·=·re.compile(WS) | 184 | RE_WS·=·re.compile(WS) |
| 185 | RE_WS_BEGIN·=·re.compile(fr'^{WSC}*') | 185 | RE_WS_BEGIN·=·re.compile(fr'^{WSC}*') |
| 186 | RE_WS_END·=·re.compile(fr'^(?:[·\t]|(?:\n\r|(?!\n\r)[\n\f\r])|{COMMENTS})*') | 186 | RE_WS_END·=·re.compile(fr'^(?:[·\t]|(?:\n\r|(?!\n\r)[\n\f\r])|{COMMENTS})*') |
| 187 | RE_CUSTOM·=·re.compile(fr'^{PAT_PSEUDO_CLASS_CUSTOM}$',·re.X) | 187 | RE_CUSTOM·=·re.compile(fr'^{PAT_PSEUDO_CLASS_CUSTOM}$',·re.X) |
| 188 | RE_PSEUDO_CLASS_SPECIAL·=·re.compile(PAT_PSEUDO_CLASS_SPECIAL,·re.I·|·re.X·|·re.U) | 188 | RE_PSEUDO_CLASS_SPECIAL·=·re.compile(PAT_PSEUDO_CLASS_SPECIAL,·re.I·|·re.X·|·re.U) |
| 189 | QUOTED·=·("'",·'"') | ||
| 189 | #·Constants | 190 | #·Constants |
| 190 | #·List·split·token | 191 | #·List·split·token |
| 191 | COMMA_COMBINATOR·=·',' | 192 | COMMA_COMBINATOR·=·',' |
| 192 | #·Relation·token·for·descendant | 193 | #·Relation·token·for·descendant |
| 193 | WS_COMBINATOR·=·"·" | 194 | WS_COMBINATOR·=·"·" |
| 194 | #·Parse·flags | 195 | #·Parse·flags |
| Offset 250, 15 lines modified | Offset 252, 15 lines modified | ||
| 250 | ················raise·SelectorSyntaxError(f"The·name·'{name}'·is·not·a·valid·custom·pseudo-class·name") | 252 | ················raise·SelectorSyntaxError(f"The·name·'{name}'·is·not·a·valid·custom·pseudo-class·name") |
| 251 | ············if·name·in·custom_selectors: | 253 | ············if·name·in·custom_selectors: |
| 252 | ················raise·KeyError(f"The·custom·selector·'{name}'·has·already·been·registered") | 254 | ················raise·KeyError(f"The·custom·selector·'{name}'·has·already·been·registered") |
| 253 | ············custom_selectors[css_unescape(name)]·=·value | 255 | ············custom_selectors[css_unescape(name)]·=·value |
| 254 | ····return·custom_selectors | 256 | ····return·custom_selectors |
| 255 | def·css_unescape(content:·str | 257 | def·css_unescape(content:·str)·->·str: |
| 256 | ····""" | 258 | ····""" |
| 257 | ····Unescape·CSS·value. | 259 | ····Unescape·CSS·value. |
| 258 | ····Strings·allow·for·spanning·the·value·on·multiple·strings·by·escaping·a·new·line. | 260 | ····Strings·allow·for·spanning·the·value·on·multiple·strings·by·escaping·a·new·line. |
| 259 | ····""" | 261 | ····""" |
| 260 | ····def·replace(m:·Match[str])·->·str: | 262 | ····def·replace(m:·Match[str])·->·str: |
| Offset 274, 15 lines modified | Offset 276, 19 lines modified | ||
| 274 | ········elif·m.group(3): | 276 | ········elif·m.group(3): |
| 275 | ············value·=·'\ufffd' | 277 | ············value·=·'\ufffd' |
| 276 | ········else: | 278 | ········else: |
| 277 | ············value·=·'' | 279 | ············value·=·'' |
| 278 | ········return·value | 280 | ········return·value |
| 279 | ···· | 281 | ····quoted·=·content.startswith(QUOTED) |
| 282 | ····return·(RE_CSS_STR_ESC·if·quoted·else·RE_CSS_ESC).sub( | ||
| 283 | ········replace, | ||
| 284 | ········content[1:-1]·if·quoted·else·content | ||
| 285 | ····) | ||
| 280 | def·escape(ident:·str)·->·str: | 286 | def·escape(ident:·str)·->·str: |
| 281 | ····"""Escape·identifier.""" | 287 | ····"""Escape·identifier.""" |
| 282 | ····string·=·[] | 288 | ····string·=·[] |
| 283 | ····length·=·len(ident) | 289 | ····length·=·len(ident) |
| Offset 684, 17 lines modified | Offset 690, 18 lines modified | ||
| 684 | ········self.pattern·=·selector.replace('\x00',·'\ufffd') | 690 | ········self.pattern·=·selector.replace('\x00',·'\ufffd') |
| 685 | ········self.flags·=·flags | 691 | ········self.flags·=·flags |
| 686 | ········self.debug·=·self.flags·&·util.DEBUG | 692 | ········self.debug·=·self.flags·&·util.DEBUG |
| 687 | ········self.custom·=·{}·if·custom·is·None·else·custom | 693 | ········self.custom·=·{}·if·custom·is·None·else·custom |
| 688 | ········self.count·=·0 | 694 | ········self.count·=·0 |
| 689 | ····def·c | 695 | ····def·increment_count(self,·increment:·int·=·1)·->·None: |
| 690 | ········"""Check·the·current·selector·count.""" | 696 | ········"""Check·the·current·selector·count.""" |
| 697 | ········self.count·+=·increment | ||
| 691 | ········if·self.count·>·SELECTOR_LIMIT: | 698 | ········if·self.count·>·SELECTOR_LIMIT: |
| 692 | ············raise·ValueError(f'Selector·exceeds·pseudo-class·nesting·limit·of·{SELECTOR_LIMIT}') | 699 | ············raise·ValueError(f'Selector·exceeds·pseudo-class·nesting·limit·of·{SELECTOR_LIMIT}') |
| 693 | ····def·parse_attribute_selector(self,·sel:·_Selector,·m:·Match[str],·has_selector:·bool)·->·bool: | 700 | ····def·parse_attribute_selector(self,·sel:·_Selector,·m:·Match[str],·has_selector:·bool)·->·bool: |
| 694 | ········"""Create·attribute·selector·from·the·returned·regex·match.""" | 701 | ········"""Create·attribute·selector·from·the·returned·regex·match.""" |
| 695 | ········inverse·=·False | 702 | ········inverse·=·False |
| Offset 711, 36 lines modified | Offset 718, 38 lines modified | ||
| 711 | ········elif·util.lower(attr)·==·'type': | 718 | ········elif·util.lower(attr)·==·'type': |
| 712 | ············flags·=·re.I·|·re.DOTALL | 719 | ············flags·=·re.I·|·re.DOTALL |
| 713 | ············is_type·=·True | 720 | ············is_type·=·True |
| 714 | ········else: | 721 | ········else: |
| 715 | ············flags·=·re.DOTALL | 722 | ············flags·=·re.DOTALL |
| 716 | ········if·op: | 723 | ········if·op: |
| 717 | ············if·m.group('value').startswith(('"',·"'")): | ||
| 718 | ················value·=·css_unescape(m.group('value')[1:-1],·True) | ||
| 719 | ············else: | ||
| 720 | ············ | 724 | ············value·=·css_unescape(m.group('value')) |
| 721 | ········if·not·op: | 725 | ········if·not·op: |
| 722 | ············#·Attribute·name | 726 | ············#·Attribute·name |
| 723 | ············pattern·=·None | 727 | ············pattern·=·None |
| 724 | ········elif·op.startswith('^'): | 728 | ········elif·op.startswith('^'): |
| 725 | ············#·Value·start·with | 729 | ············#·Value·start·with |
| 730 | ············#·`^=`·should·match·nothing·if·the·value·is·empty,·so·use·`(?!)`·which·cannot·be·matched. | ||
| 731 | ············value·=·r'(?!)'·if·not·value·else·re.escape(value) | ||
| 726 | ············pattern·=·re.compile(r'^%s.*'·%· | 732 | ············pattern·=·re.compile(r'^%s.*'·%·value,·flags) |
| 727 | ········elif·op.startswith('$'): | 733 | ········elif·op.startswith('$'): |
| 728 | ············#·Value·ends·with | 734 | ············#·Value·ends·with |
| 735 | ············#·`$=`·should·match·nothing·if·the·value·is·empty,·so·use·`(?!)`·which·cannot·be·matched. | ||
| 736 | ············value·=·r'(?!)'·if·not·value·else·re.escape(value) | ||
| 729 | ············pattern·=·re.compile(r'.*?%s$'·%· | 737 | ············pattern·=·re.compile(r'.*?%s$'·%·value,·flags) |
| 730 | ········elif·op.startswith('*'): | 738 | ········elif·op.startswith('*'): |
| 731 | ············#·Value·contains | 739 | ············#·Value·contains |
| 740 | ············#·`*=`·should·match·nothing·if·the·value·is·empty,·so·use·`(?!)`·which·cannot·be·matched. | ||
| 741 | ············value·=·r'(?!)'·if·not·value·else·re.escape(value) | ||
| 732 | ············pattern·=·re.compile(r'.*?%s.*'·%· | 742 | ············pattern·=·re.compile(r'.*?%s.*'·%·value,·flags) |
| 733 | ········elif·op.startswith('~'): | 743 | ········elif·op.startswith('~'): |
| 734 | ············#·Value·contains·word·within·space·separated·list | 744 | ············#·Value·contains·word·within·space·separated·list |
| 745 | ············#·`*~`·should·match·nothing·if·the·value·is·empty,·so·use·`(?!)`·which·cannot·be·matched. | ||
| 735 | ············#·`~=`·should·match·nothing·if·it·is·empty·or·contains·whitespace, | ||
| 736 | ············#·so·if·either·of·these·cases·is·present,·use·`[^\s\S]`·which·cannot·be·matched. | ||
| 737 | ············value·=·r' | 746 | ············value·=·r'(?!)'·if·not·value·or·RE_WS.search(value)·else·re.escape(value) |
| 738 | ············pattern·=·re.compile(r'.*?(?:(?<=^)|(?<=[·\t\r\n\f]))%s(?=(?:[·\t\r\n\f]|$)).*'·%·value,·flags) | 747 | ············pattern·=·re.compile(r'.*?(?:(?<=^)|(?<=[·\t\r\n\f]))%s(?=(?:[·\t\r\n\f]|$)).*'·%·value,·flags) |
| 739 | ········elif·op.startswith('|'): | 748 | ········elif·op.startswith('|'): |
| 740 | ············#·Value·starts·with·word·in·dash·separated·list | 749 | ············#·Value·starts·with·word·in·dash·separated·list |
| 741 | ············pattern·=·re.compile(r'^%s(?:-.*)?$'·%·re.escape(value),·flags) | 750 | ············pattern·=·re.compile(r'^%s(?:-.*)?$'·%·re.escape(value),·flags) |
| 742 | ········else: | 751 | ········else: |
| 743 | ············#·Value·matches | 752 | ············#·Value·matches |
| 744 | ············pattern·=·re.compile(r'^%s$'·%·re.escape(value),·flags) | 753 | ············pattern·=·re.compile(r'^%s$'·%·re.escape(value),·flags) |
| Offset 793, 17 lines modified | Offset 802, 15 lines modified | ||
| 793 | ········if·not·isinstance(selector,·ct.SelectorList): | 802 | ········if·not·isinstance(selector,·ct.SelectorList): |
| 794 | ············del·self.custom[pseudo] | 803 | ············del·self.custom[pseudo] |
| 795 | ············selector·=·CSSParser( | 804 | ············selector·=·CSSParser( |
| 796 | ················selector,·custom=self.custom,·flags=self.flags | 805 | ················selector,·custom=self.custom,·flags=self.flags |
| 797 | ············).process_selectors(flags=FLG_PSEUDO) | 806 | ············).process_selectors(flags=FLG_PSEUDO) |
| 798 | ············self.custom[pseudo]·=·selector | 807 | ············self.custom[pseudo]·=·selector |
| 799 | ········self.c | 808 | ········self.increment_count(selector.count) |
| 800 | ········self.check_count() | ||
| 801 | ········sel.selectors.append(selector) | 809 | ········sel.selectors.append(selector) |
| Max diff block lines reached; 7014/12444 bytes (56.36%) of diff not shown. | |||
| Offset 18, 40 lines modified | Offset 18, 52 lines modified | ||
| 18 | ········$·python·-m·svglib·foo.svg | 18 | ········$·python·-m·svglib·foo.svg |
| 19 | """ | 19 | """ |
| 20 | import·base64 | 20 | import·base64 |
| 21 | import·copy | 21 | import·copy |
| 22 | import·gzip | 22 | import·gzip |
| 23 | import·itertools | 23 | import·itertools |
| 24 | import·locale | ||
| 25 | import·logging | 24 | import·logging |
| 26 | import·os | 25 | import·os |
| 27 | import·pathlib | 26 | import·pathlib |
| 28 | import·re | 27 | import·re |
| 29 | import·shlex | 28 | import·shlex |
| 30 | import·shutil | 29 | import·shutil |
| 31 | import·sys | ||
| 32 | from·collections·import·defaultdict,·namedtuple | 30 | from·collections·import·defaultdict,·namedtuple |
| 33 | from·io·import·BytesIO | 31 | from·io·import·BytesIO |
| 34 | from·typing·import· | 32 | from·typing·import·( |
| 33 | ····Any, | ||
| 34 | ····BinaryIO, | ||
| 35 | ····Dict, | ||
| 36 | ····List, | ||
| 37 | ····Optional, | ||
| 38 | ····Set, | ||
| 39 | ····TextIO, | ||
| 40 | ····Tuple, | ||
| 41 | ····TypedDict, | ||
| 42 | ····Union, | ||
| 43 | ····cast, | ||
| 44 | ) | ||
| 35 | from·PIL·import·Image·as·PILImage | 45 | from·PIL·import·Image·as·PILImage |
| 46 | from·reportlab.graphics.renderSVG·import·SVGCanvas | ||
| 36 | from·reportlab.graphics.shapes·import·( | 47 | from·reportlab.graphics.shapes·import·( |
| 37 | ····_CLOSEPATH, | 48 | ····_CLOSEPATH, |
| 38 | ····Circle, | 49 | ····Circle, |
| 39 | ····DirectDraw, | 50 | ····DirectDraw, |
| 40 | ····Drawing, | 51 | ····Drawing, |
| 41 | ····Ellipse, | 52 | ····Ellipse, |
| 42 | ····Group, | 53 | ····Group, |
| 43 | ····Image, | 54 | ····Image, |
| 44 | ····Line, | 55 | ····Line, |
| 45 | ····Path, | 56 | ····Path, |
| 46 | ····Polygon, | 57 | ····Polygon, |
| 47 | ····PolyLine, | 58 | ····PolyLine, |
| 48 | ····Rect, | 59 | ····Rect, |
| 60 | ····Shape, | ||
| 49 | ····SolidShape, | 61 | ····SolidShape, |
| 50 | ····String, | 62 | ····String, |
| 51 | ····_renderPath, | 63 | ····_renderPath, |
| 52 | ) | 64 | ) |
| 53 | from·reportlab.lib·import·colors | 65 | from·reportlab.lib·import·colors |
| 54 | from·reportlab.lib.units·import·toLength | 66 | from·reportlab.lib.units·import·toLength |
| 55 | from·reportlab.pdfbase.pdfmetrics·import·stringWidth | 67 | from·reportlab.pdfbase.pdfmetrics·import·stringWidth |
| Offset 89, 14 lines modified | Offset 101, 48 lines modified | ||
| 89 | ····convert_quadratic_to_cubic_path, | 101 | ····convert_quadratic_to_cubic_path, |
| 90 | ····normalise_svg_path, | 102 | ····normalise_svg_path, |
| 91 | ) | 103 | ) |
| 92 | #·SVG·user·units·are·px;·ReportLab·works·in·points.··1·px·=·0.75·pt·(96·dpi·/·72·dpi). | 104 | #·SVG·user·units·are·px;·ReportLab·works·in·points.··1·px·=·0.75·pt·(96·dpi·/·72·dpi). |
| 93 | PX_TO_PT·=·0.75 | 105 | PX_TO_PT·=·0.75 |
| 106 | #·An·SVG·source·accepted·by·the·public·API:·a·path,·a·path-like·object,·or·an | ||
| 107 | #·already-open·binary/text·file·object. | ||
| 108 | SVGSource·=·Union[str,·os.PathLike[str],·BinaryIO,·TextIO] | ||
| 109 | #·A·single·gradient·stop:·(offset,·ReportLab·color).·The·color·is·untyped | ||
| 110 | #·because·ReportLab·ships·no·stubs. | ||
| 111 | GradientStop·=·Tuple[float,·Any] | ||
| 112 | class·_GradientDefBase(TypedDict): | ||
| 113 | ····"""Keys·always·present·on·a·parsed·gradient·definition.""" | ||
| 114 | ····type:·str··#·"linear"·or·"radial" | ||
| 115 | ····gradientUnits:·str | ||
| 116 | ····spreadMethod:·str | ||
| 117 | ····stops:·List[GradientStop] | ||
| 118 | ····href:·Optional[str] | ||
| 119 | class·_GradientDef(_GradientDefBase,·total=False): | ||
| 120 | ····"""Geometry·keys·present·depending·on·``type``·(linear·vs·radial).""" | ||
| 121 | ····#·linearGradient | ||
| 122 | ····x1:·float | ||
| 123 | ····y1:·float | ||
| 124 | ····x2:·float | ||
| 125 | ····y2:·float | ||
| 126 | ····#·radialGradient | ||
| 127 | ····cx:·float | ||
| 128 | ····cy:·float | ||
| 129 | ····r:·float | ||
| 130 | ····fx:·float | ||
| 131 | ····fy:·float | ||
| 94 | def·_convert_palette_to_rgba(image:·PILImage.Image)·->·PILImage.Image: | 132 | def·_convert_palette_to_rgba(image:·PILImage.Image)·->·PILImage.Image: |
| 95 | ····"""Convert·a·palette-based·image·with·transparency·to·RGBA·format. | 133 | ····"""Convert·a·palette-based·image·with·transparency·to·RGBA·format. |
| 96 | ····This·function·checks·if·a·PIL·Image·is·in·palette·mode·('P')·and·has | 134 | ····This·function·checks·if·a·PIL·Image·is·in·palette·mode·('P')·and·has |
| 97 | ····transparency·information.·If·so,·it·converts·the·image·to·RGBA·to·prevent | 135 | ····transparency·information.·If·so,·it·converts·the·image·to·RGBA·to·prevent |
| 98 | ····potential·warnings·or·errors·during·processing. | 136 | ····potential·warnings·or·errors·during·processing. |
| Offset 232, 22 lines modified | Offset 278, 23 lines modified | ||
| 232 | ····"""A·Path·object·that·never·has·a·stroke·width. | 278 | ····"""A·Path·object·that·never·has·a·stroke·width. |
| 233 | ····This·class·is·used·to·create·filled·shapes·from·unclosed·paths,·where | 279 | ····This·class·is·used·to·create·filled·shapes·from·unclosed·paths,·where |
| 234 | ····only·the·fill·should·be·rendered·and·the·stroke·should·be·ignored. | 280 | ····only·the·fill·should·be·rendered·and·the·stroke·should·be·ignored. |
| 235 | ····""" | 281 | ····""" |
| 236 | ····def·__init__(self,·*args:·Any,·**kwargs:·Any)·->·None: | 282 | ····def·__init__(self,·*args:·Any,·**kwargs:·Any)·->·None: |
| 283 | ········"""Initialize·the·path,·optionally·copying·state·from·another·shape.""" | ||
| 237 | ········copy_from·=·kwargs.pop("copy_from",·None) | 284 | ········copy_from·=·kwargs.pop("copy_from",·None) |
| 238 | ········super().__init__(*args,·**kwargs) | 285 | ········super().__init__(*args,·**kwargs) |
| 239 | ········if·copy_from: | 286 | ········if·copy_from: |
| 240 | ············self.__dict__.update(copy.deepcopy(copy_from.__dict__)) | 287 | ············self.__dict__.update(copy.deepcopy(copy_from.__dict__)) |
| 241 | ····def·getProperties(self,·*args:·Any,·**kwargs:·Any)·->·Dict[str,·Any]: | 288 | ····def·getProperties(self,·*args:·Any,·**kwargs:·Any)·->·Dict[str,·Any]: |
| 242 | ········"""Return·the·properties·of·the·path,·ensuring·no·stroke·is·applied.""" | 289 | ········"""Return·the·properties·of·the·path,·ensuring·no·stroke·is·applied.""" |
| 243 | ········props·=·super().getProperties(*args,·**kwargs) | 290 | ········props:·Dict[str,·Any]·=·super().getProperties(*args,·**kwargs) |
| 244 | ········if·"strokeWidth"·in·props: | 291 | ········if·"strokeWidth"·in·props: |
| 245 | ············props["strokeWidth"]·=·0 | 292 | ············props["strokeWidth"]·=·0 |
| 246 | ········if·"strokeColor"·in·props: | 293 | ········if·"strokeColor"·in·props: |
| 247 | ············props["strokeColor"]·=·None | 294 | ············props["strokeColor"]·=·None |
| 248 | ········return·props | 295 | ········return·props |
| Max diff block lines reached; 57912/61426 bytes (94.28%) of diff not shown. | |||
| Offset 1, 10 lines modified | Offset 1, 10 lines modified | ||
| 1 | Metadata-Version:·2.4 | 1 | Metadata-Version:·2.4 |
| 2 | Name:·filelock | 2 | Name:·filelock |
| 3 | Version:·3.3 | 3 | Version:·3.32.2 |
| 4 | Summary:·A·platform·independent·file·lock. | 4 | Summary:·A·platform·independent·file·lock. |
| 5 | Project-URL:·Documentation,·https://py-filelock.readthedocs.io | 5 | Project-URL:·Documentation,·https://py-filelock.readthedocs.io |
| 6 | Project-URL:·Homepage,·https://github.com/tox-dev/py-filelock | 6 | Project-URL:·Homepage,·https://github.com/tox-dev/py-filelock |
| 7 | Project-URL:·Source,·https://github.com/tox-dev/py-filelock | 7 | Project-URL:·Source,·https://github.com/tox-dev/py-filelock |
| 8 | Project-URL:·Tracker,·https://github.com/tox-dev/py-filelock/issues | 8 | Project-URL:·Tracker,·https://github.com/tox-dev/py-filelock/issues |
| 9 | Maintainer-email:·Bernát·Gábor·<gaborjbernat@gmail.com> | 9 | Maintainer-email:·Bernát·Gábor·<gaborjbernat@gmail.com> |
| 10 | License-Expression:·MIT | 10 | License-Expression:·MIT |
| Offset 17, 14 lines modified | Offset 17, 15 lines modified | ||
| 17 | Classifier:·Programming·Language·::·Python | 17 | Classifier:·Programming·Language·::·Python |
| 18 | Classifier:·Programming·Language·::·Python·::·3·::·Only | 18 | Classifier:·Programming·Language·::·Python·::·3·::·Only |
| 19 | Classifier:·Programming·Language·::·Python·::·3.10 | 19 | Classifier:·Programming·Language·::·Python·::·3.10 |
| 20 | Classifier:·Programming·Language·::·Python·::·3.11 | 20 | Classifier:·Programming·Language·::·Python·::·3.11 |
| 21 | Classifier:·Programming·Language·::·Python·::·3.12 | 21 | Classifier:·Programming·Language·::·Python·::·3.12 |
| 22 | Classifier:·Programming·Language·::·Python·::·3.13 | 22 | Classifier:·Programming·Language·::·Python·::·3.13 |
| 23 | Classifier:·Programming·Language·::·Python·::·3.14 | 23 | Classifier:·Programming·Language·::·Python·::·3.14 |
| 24 | Classifier:·Programming·Language·::·Python·::·3.15 | ||
| 24 | Classifier:·Topic·::·Internet | 25 | Classifier:·Topic·::·Internet |
| 25 | Classifier:·Topic·::·Software·Development·::·Libraries | 26 | Classifier:·Topic·::·Software·Development·::·Libraries |
| 26 | Classifier:·Topic·::·System | 27 | Classifier:·Topic·::·System |
| 27 | Requires-Python:·>=3.10 | 28 | Requires-Python:·>=3.10 |
| 28 | Description-Content-Type:·text/markdown | 29 | Description-Content-Type:·text/markdown |
| 29 | #·filelock | 30 | #·filelock |
| Offset 1, 10 lines modified | Offset 1, 10 lines modified | ||
| 1 | Metadata-Version:·2.4 | 1 | Metadata-Version:·2.4 |
| 2 | Name:·soupsieve | 2 | Name:·soupsieve |
| 3 | Version:·2.9 | 3 | Version:·2.9.2 |
| 4 | Summary:·A·modern·CSS·selector·implementation·for·Beautiful·Soup. | 4 | Summary:·A·modern·CSS·selector·implementation·for·Beautiful·Soup. |
| 5 | Project-URL:·Homepage,·https://github.com/facelessuser/soupsieve | 5 | Project-URL:·Homepage,·https://github.com/facelessuser/soupsieve |
| 6 | Author-email:·Isaac·Muse·<Isaac.Muse@gmail.com> | 6 | Author-email:·Isaac·Muse·<Isaac.Muse@gmail.com> |
| 7 | License-Expression:·MIT | 7 | License-Expression:·MIT |
| 8 | License-File:·LICENSE.md | 8 | License-File:·LICENSE.md |
| 9 | Keywords:·CSS,HTML,XML,filter,query,selector,soup | 9 | Keywords:·CSS,HTML,XML,filter,query,selector,soup |
| 10 | Classifier:·Development·Status·::·5·-·Production/Stable | 10 | Classifier:·Development·Status·::·5·-·Production/Stable |
| Offset 1, 10 lines modified | Offset 1, 10 lines modified | ||
| 1 | Metadata-Version:·2.4 | 1 | Metadata-Version:·2.4 |
| 2 | Name:·svglib | 2 | Name:·svglib |
| 3 | Version:·2. | 3 | Version:·2.1.0 |
| 4 | Summary:·A·pure-Python·library·for·reading·and·converting·SVG | 4 | Summary:·A·pure-Python·library·for·reading·and·converting·SVG |
| 5 | Project-URL:·Homepage,·https://github.com/deeplook/svglib | 5 | Project-URL:·Homepage,·https://github.com/deeplook/svglib |
| 6 | Author:·Dinu·Gherman | 6 | Author:·Dinu·Gherman |
| 7 | License-Expression:·LGPL-3.0-or-later | 7 | License-Expression:·LGPL-3.0-or-later |
| 8 | License-File:·LICENSE.txt | 8 | License-File:·LICENSE.txt |
| 9 | Keywords:·PDF,SVG,conversion,graphics,reportlab | 9 | Keywords:·PDF,SVG,conversion,graphics,reportlab |
| 10 | Classifier:·Development·Status·::·5·-·Production/Stable | 10 | Classifier:·Development·Status·::·5·-·Production/Stable |
| Offset 19, 14 lines modified | Offset 19, 15 lines modified | ||
| 19 | Classifier:·Programming·Language·::·Python | 19 | Classifier:·Programming·Language·::·Python |
| 20 | Classifier:·Programming·Language·::·Python·::·3·::·Only | 20 | Classifier:·Programming·Language·::·Python·::·3·::·Only |
| 21 | Classifier:·Programming·Language·::·Python·::·3.9 | 21 | Classifier:·Programming·Language·::·Python·::·3.9 |
| 22 | Classifier:·Programming·Language·::·Python·::·3.10 | 22 | Classifier:·Programming·Language·::·Python·::·3.10 |
| 23 | Classifier:·Programming·Language·::·Python·::·3.11 | 23 | Classifier:·Programming·Language·::·Python·::·3.11 |
| 24 | Classifier:·Programming·Language·::·Python·::·3.12 | 24 | Classifier:·Programming·Language·::·Python·::·3.12 |
| 25 | Classifier:·Programming·Language·::·Python·::·3.13 | 25 | Classifier:·Programming·Language·::·Python·::·3.13 |
| 26 | Classifier:·Programming·Language·::·Python·::·3.14 | ||
| 26 | Classifier:·Topic·::·Documentation | 27 | Classifier:·Topic·::·Documentation |
| 27 | Classifier:·Topic·::·Multimedia·::·Graphics·::·Graphics·Conversion | 28 | Classifier:·Topic·::·Multimedia·::·Graphics·::·Graphics·Conversion |
| 28 | Classifier:·Topic·::·Printing | 29 | Classifier:·Topic·::·Printing |
| 29 | Classifier:·Topic·::·Software·Development·::·Libraries·::·Python·Modules | 30 | Classifier:·Topic·::·Software·Development·::·Libraries·::·Python·Modules |
| 30 | Classifier:·Topic·::·Text·Processing·::·Markup·::·XML | 31 | Classifier:·Topic·::·Text·Processing·::·Markup·::·XML |
| 31 | Classifier:·Topic·::·Utilities | 32 | Classifier:·Topic·::·Utilities |
| 32 | Requires-Python:·>=3.9 | 33 | Requires-Python:·>=3.9 |
| Offset 94, 15 lines modified | Offset 95, 17 lines modified | ||
| 94 | -·support·Python·3.9+·and·PyPy3 | 95 | -·support·Python·3.9+·and·PyPy3 |
| 95 | ##·Known·limitations | 96 | ##·Known·limitations |
| 96 | -·`@import`·rules·in·stylesheets·are·ignored.·CSS·is·supported,·but·the·range | 97 | -·`@import`·rules·in·stylesheets·are·ignored.·CSS·is·supported,·but·the·range |
| 97 | ··of·supported·attributes·is·still·limited | 98 | ··of·supported·attributes·is·still·limited |
| 98 | -·clipp | 99 | -·clip·paths·support·`path`,·`rect`,·`circle`,·`ellipse`·and·`polygon`·shapes, |
| 100 | ··but·only·one·`clip-rule`·per·`clipPath`. | ||
| 101 | -·SVG·`mask`·elements·are·not·supported | ||
| 99 | -·SVG·`ForeignObject`·elements·are·not·supported. | 102 | -·SVG·`ForeignObject`·elements·are·not·supported. |
| 100 | ##·Examples | 103 | ##·Examples |
| 101 | You·can·use·`svglib`·as·a·Python·package·e.g.·like·in·the·following | 104 | You·can·use·`svglib`·as·a·Python·package·e.g.·like·in·the·following |
| 102 | interactive·Python·session: | 105 | interactive·Python·session: |
| Offset 37, 15 lines modified | Offset 37, 15 lines modified | ||
| 37 | ········"bootstrap-native/x86_64/math.so":·"b5514fd77493532a51329d69d45b17d386dce4ec", | 37 | ········"bootstrap-native/x86_64/math.so":·"b5514fd77493532a51329d69d45b17d386dce4ec", |
| 38 | ········"bootstrap-native/x86_64/mmap.so":·"59d5bdc3daf49510b555e4b5ccfc3182646a8a4d", | 38 | ········"bootstrap-native/x86_64/mmap.so":·"59d5bdc3daf49510b555e4b5ccfc3182646a8a4d", |
| 39 | ········"bootstrap-native/x86_64/zlib.so":·"53c15fa2d19cdace60b2828b8e2af1f32e33c5bc", | 39 | ········"bootstrap-native/x86_64/zlib.so":·"53c15fa2d19cdace60b2828b8e2af1f32e33c5bc", |
| 40 | ········"bootstrap.imy":·"41a0b4122ce32432b247645932cfb831357a7724", | 40 | ········"bootstrap.imy":·"41a0b4122ce32432b247645932cfb831357a7724", |
| 41 | ········"cacert.pem":·"2c68212e96605210eddf740291862bdf59398aef", | 41 | ········"cacert.pem":·"2c68212e96605210eddf740291862bdf59398aef", |
| 42 | ········"requirements-arm64-v8a.imy":·"d1c15a21c79bbfb2a21969983a5c3aa363e3572a", | 42 | ········"requirements-arm64-v8a.imy":·"d1c15a21c79bbfb2a21969983a5c3aa363e3572a", |
| 43 | ········"requirements-armeabi-v7a.imy":·"d6dc32d2d5d01480de10ad32b4f4b3084ad2e5e6", | 43 | ········"requirements-armeabi-v7a.imy":·"d6dc32d2d5d01480de10ad32b4f4b3084ad2e5e6", |
| 44 | ········"requirements-common.imy":·" | 44 | ········"requirements-common.imy":·"f8faa1929931e750581957471fea992351ff676d", |
| 45 | ········"requirements-x86_64.imy":·"117873e944235279c1b5cdf8a23cb1ae7bf6cc47", | 45 | ········"requirements-x86_64.imy":·"117873e944235279c1b5cdf8a23cb1ae7bf6cc47", |
| 46 | ········"stdlib-arm64-v8a.imy":·"612b92fdeb357374b9d1742707428de8814a2470", | 46 | ········"stdlib-arm64-v8a.imy":·"612b92fdeb357374b9d1742707428de8814a2470", |
| 47 | ········"stdlib-armeabi-v7a.imy":·"cd04ebaad8bba14a5bcdc665671090da5631b967", | 47 | ········"stdlib-armeabi-v7a.imy":·"cd04ebaad8bba14a5bcdc665671090da5631b967", |
| 48 | ········"stdlib-common.imy":·"e17aea5e7f5d5ef8c9cc260620409eaf7b4bb33b", | 48 | ········"stdlib-common.imy":·"e17aea5e7f5d5ef8c9cc260620409eaf7b4bb33b", |
| 49 | ········"stdlib-x86_64.imy":·"43e3c83dba14e01cd82f0167a4152d3c1dbdcc25" | 49 | ········"stdlib-x86_64.imy":·"43e3c83dba14e01cd82f0167a4152d3c1dbdcc25" |
| 50 | ····}, | 50 | ····}, |
| 51 | ····"extract_packages":·[ | 51 | ····"extract_packages":·[ |