2.7 MB
/home/fdroid/fdroiddata/tmp/com.econverter.app_7.apk vs.
/home/fdroid/fdroiddata/unsigned/com.econverter.app_7.apk
8.2 KB
APK Signing Block
    
Offset 1, 121 lines modifiedOffset 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 
3.02 KB
zipinfo {}
    
Offset 1, 8 lines modifiedOffset 1, 8 lines modified
1 Zip·file·size:·63374044·bytes,·number·of·entries:·2181 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.properties2 -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.textproto3 -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.prof4 -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.profm5 -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.dex6 -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.dex7 -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.so8 -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 modifiedOffset 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.so70 -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.so71 -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.imy72 -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.json73 -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.pem74 -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.imy75 -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.imy76 -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··3733210·b-·stor·81-Jan-01·01:01·assets/chaquopy/requirements-common.imy77 -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.imy78 -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.imy79 -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.imy80 -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.imy81 -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.imy82 -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.bin83 -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.version84 -rw----·····2.4·fat········6·b-·stor·81-Jan-01·01:01·META-INF/androidx.activity_activity-compose.version
Offset 210, 11 lines modifiedOffset 210, 8 lines modified
210 -rw----·····0.0·fat······225·b-·stor·81-Jan-01·01:01·res/wN.9.png210 -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.xml211 -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.png212 -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.png213 -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.png214 -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.png215 -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.arsc216 -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 218·files,·74752876·bytes·uncompressed,·62843247·bytes·compressed:··15.9%217 215·files,·74712953·bytes·uncompressed,·62832225·bytes·compressed:··15.9%
2.69 MB
assets/chaquopy/requirements-common.imy
10.1 KB
zipinfo {}
    
Offset 1, 8 lines modifiedOffset 1, 8 lines modified
1 Zip·file·size:·3733210·bytes,·number·of·entries:·7731 Zip·file·size:·3739796·bytes,·number·of·entries:·773
2 -rw----·····2.0·fat····34703·b-·defN·80-Feb-01·00:00·six.py2 -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.py3 -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.py5 -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.py6 -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.py7 -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.py8 -rw----·····2.0·fat·····1753·b-·defN·80-Feb-01·00:00·PIL/BufrStubImagePlugin.py
Offset 276, 42 lines modifiedOffset 276, 42 lines modified
276 -rw----·····2.0·fat·····5364·b-·defN·80-Feb-01·00:00·defusedxml/xmlrpc.py276 -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/INSTALLER278 -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/LICENSE279 -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/METADATA280 -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.txt281 -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·····3533·b-·defN·80-Feb-01·00:00·filelock/__init__.py283 -rw----·····2.0·fat·····3469·b-·defN·80-Feb-01·00:00·filelock/__init__.py
284 -rw----·····2.0·fat····81745·b-·defN·80-Feb-01·00:00·filelock/_api.py284 -rw----·····2.0·fat····82263·b-·defN·80-Feb-01·00:00·filelock/_api.py
285 -rw----·····2.0·fat·····5209·b-·defN·80-Feb-01·00:00·filelock/_async.py285 -rw----·····2.0·fat·····6111·b-·defN·80-Feb-01·00:00·filelock/_async.py
286 -rw----·····2.0·fat····13675·b-·defN·80-Feb-01·00:00·filelock/_async_read_write.py286 -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.py287 -rw----·····2.0·fat·····2981·b-·defN·80-Feb-01·00:00·filelock/_descriptor.py
288 -rw----·····2.0·fat·····2549·b-·defN·80-Feb-01·00:00·filelock/_error.py288 -rw----·····2.0·fat·····2699·b-·defN·80-Feb-01·00:00·filelock/_error.py
289 -rw----·····2.0·fat·····8322·b-·defN·80-Feb-01·00:00·filelock/_identity.py289 -rw----·····2.0·fat·····8415·b-·defN·80-Feb-01·00:00·filelock/_identity.py
290 -rw----·····2.0·fat····12510·b-·defN·80-Feb-01·00:00·filelock/_lease.py290 -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.py291 -rw----·····2.0·fat·····6026·b-·defN·80-Feb-01·00:00·filelock/_marker.py
292 -rw----·····2.0·fat····32701·b-·defN·80-Feb-01·00:00·filelock/_read_write.py292 -rw----·····2.0·fat····32895·b-·defN·80-Feb-01·00:00·filelock/_read_write.py
293 -rw----·····2.0·fat····12865·b-·defN·80-Feb-01·00:00·filelock/_soft.py293 -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.py294 -rw----·····2.0·fat······187·b-·defN·80-Feb-01·00:00·filelock/_soft_protocol.py
295 -rw----·····2.0·fat····37274·b-·defN·80-Feb-01·00:00·filelock/_strict.py295 -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.py296 -rw----·····2.0·fat·····8722·b-·defN·80-Feb-01·00:00·filelock/_unix.py
297 -rw----·····2.0·fat·····6330·b-·defN·80-Feb-01·00:00·filelock/_util.py297 -rw----·····2.0·fat·····6356·b-·defN·80-Feb-01·00:00·filelock/_util.py
298 -rw----·····2.0·fat····15645·b-·defN·80-Feb-01·00:00·filelock/_windows.py298 -rw----·····2.0·fat····15988·b-·defN·80-Feb-01·00:00·filelock/_windows.py
299 -rw----·····2.0·fat····34463·b-·defN·80-Feb-01·00:00·filelock/asyncio.py299 -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.typed300 -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.py301 -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__.py303 -rw----·····2.0·fat······370·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/__init__.py
304 -rw----·····2.0·fat·····9261·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/_async.py304 -rw----·····2.0·fat····11492·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/_async.py
305 -rw----·····2.0·fat····41844·b-·defN·80-Feb-01·00:00·filelock/_soft_rw/_sync.py305 -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.31.0.dist-info/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.31.0.dist-info/INSTALLER307 -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·filelock-3.32.2.dist-info/INSTALLER
308 -rw----·····2.0·fat·····1977·b-·defN·80-Feb-01·00:00·filelock-3.31.0.dist-info/METADATA308 -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.31.0.dist-info/licenses/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.31.0.dist-info/licenses/LICENSE310 -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__.py312 -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__.py313 -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.py314 -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.py315 -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.py316 -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.py317 -rw----·····2.0·fat·····4052·b-·defN·80-Feb-01·00:00·html2text/config.py
Offset 687, 36 lines modifiedOffset 687, 36 lines modified
687 -rw----·····2.0·fat·····1066·b-·defN·80-Feb-01·00:00·six-1.17.0.dist-info/LICENSE687 -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/METADATA688 -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.txt689 -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__.py691 -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__.py692 -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.py693 -rw----·····2.0·fat····60276·b-·defN·80-Feb-01·00:00·soupsieve/css_match.py
694 -rw----·····2.0·fat····48110·b-·defN·80-Feb-01·00:00·soupsieve/css_parser.py694 -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.py695 -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.py696 -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.typed697 -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.py698 -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/INSTALLER700 -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·soupsieve-2.9.2.dist-info/INSTALLER
701 -rw----·····2.0·fat·····4584·b-·defN·80-Feb-01·00:00·soupsieve-2.9.dist-info/METADATA701 -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.md703 -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__.py705 -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.py706 -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.typed707 -rw----·····2.0·fat········0·b-·defN·80-Feb-01·00:00·svglib/py.typed
708 -rw----·····2.0·fat····96958·b-·defN·80-Feb-01·00:00·svglib/svglib.py708 -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.py709 -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.0.2.dist-info/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.0.2.dist-info/INSTALLER711 -rw----·····2.0·fat········4·b-·defN·80-Feb-01·00:00·svglib-2.1.0.dist-info/INSTALLER
712 -rw----·····2.0·fat····13923·b-·defN·80-Feb-01·00:00·svglib-2.0.2.dist-info/METADATA712 -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.0.2.dist-info/entry_points.txt713 -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.0.2.dist-info/licenses/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.0.2.dist-info/licenses/LICENSE.txt715 -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__.py717 -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.py718 -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.py719 -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.py720 -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.py721 -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.py722 -rw----·····2.0·fat·····5118·b-·defN·80-Feb-01·00:00·tinycss/page3.py
Offset 768, 8 lines modifiedOffset 768, 8 lines modified
768 -rw----·····2.0·fat·····4307·b-·defN·80-Feb-01·00:00·webencodings/x_user_defined.py768 -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.rst770 -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/INSTALLER771 -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/METADATA772 -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.json773 -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.txt774 -rw----·····2.0·fat·······13·b-·defN·80-Feb-01·00:00·webencodings-0.5.1.dist-info/top_level.txt
775 773·files,·10885779·bytes·uncompressed,·3617692·bytes·compressed:··66.8%775 773·files,·10910665·bytes·uncompressed,·3624258·bytes·compressed:··66.8%
2.31 KB
zipnote «TEMP»/diffoscope_sde82xxt_unsigned/tmpuunqvbjv_.zip
    
Offset 906, 27 lines modifiedOffset 906, 27 lines modified
  
906 Filename:·filelock/_soft_rw/_async.py906 Filename:·filelock/_soft_rw/_async.py
907 Comment:·907 Comment:·
  
908 Filename:·filelock/_soft_rw/_sync.py908 Filename:·filelock/_soft_rw/_sync.py
909 Comment:·909 Comment:·
  
910 Filename:·filelock-3.31.0.dist-info/910 Filename:·filelock-3.32.2.dist-info/
911 Comment:·911 Comment:·
  
912 Filename:·filelock-3.31.0.dist-info/INSTALLER912 Filename:·filelock-3.32.2.dist-info/INSTALLER
913 Comment:·913 Comment:·
  
914 Filename:·filelock-3.31.0.dist-info/METADATA914 Filename:·filelock-3.32.2.dist-info/METADATA
915 Comment:·915 Comment:·
  
916 Filename:·filelock-3.31.0.dist-info/licenses/916 Filename:·filelock-3.32.2.dist-info/licenses/
917 Comment:·917 Comment:·
  
918 Filename:·filelock-3.31.0.dist-info/licenses/LICENSE918 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__.py922 Filename:·html2text/__init__.py
923 Comment:·923 Comment:·
Offset 2085, 27 lines modifiedOffset 2085, 27 lines modified
  
2085 Filename:·soupsieve/py.typed2085 Filename:·soupsieve/py.typed
2086 Comment:·2086 Comment:·
  
2087 Filename:·soupsieve/util.py2087 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/INSTALLER2091 Filename:·soupsieve-2.9.2.dist-info/INSTALLER
2092 Comment:·2092 Comment:·
  
2093 Filename:·soupsieve-2.9.dist-info/METADATA2093 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.md2097 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__.py2101 Filename:·svglib/__init__.py
2102 Comment:·2102 Comment:·
Offset 2118, 30 lines modifiedOffset 2118, 30 lines modified
  
2118 Filename:·svglib/svglib.py2118 Filename:·svglib/svglib.py
2119 Comment:·2119 Comment:·
  
2120 Filename:·svglib/utils.py2120 Filename:·svglib/utils.py
2121 Comment:·2121 Comment:·
  
2122 Filename:·svglib-2.0.2.dist-info/2122 Filename:·svglib-2.1.0.dist-info/
2123 Comment:·2123 Comment:·
  
2124 Filename:·svglib-2.0.2.dist-info/INSTALLER2124 Filename:·svglib-2.1.0.dist-info/INSTALLER
2125 Comment:·2125 Comment:·
  
2126 Filename:·svglib-2.0.2.dist-info/METADATA2126 Filename:·svglib-2.1.0.dist-info/METADATA
2127 Comment:·2127 Comment:·
  
2128 Filename:·svglib-2.0.2.dist-info/entry_points.txt2128 Filename:·svglib-2.1.0.dist-info/entry_points.txt
2129 Comment:·2129 Comment:·
  
2130 Filename:·svglib-2.0.2.dist-info/licenses/2130 Filename:·svglib-2.1.0.dist-info/licenses/
2131 Comment:·2131 Comment:·
  
2132 Filename:·svglib-2.0.2.dist-info/licenses/LICENSE.txt2132 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__.py2136 Filename:·tinycss/__init__.py
2137 Comment:·2137 Comment:·
2.5 MB
zipdetails --redact --walk --utc {}
    
Offset 6749, 32706 lines modifiedOffset 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···················E1734216·(3782427158)6756 0F430A·CRC···················013F55B0·(20927920)
6757 0F430E·Compressed·Size·······00000415·(1045)6757 0F430E·Compressed·Size·······000003EA·(1002)
6758 0F4312·Uncompressed·Size·····00000DCD·(3533)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·filename6764 #··········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···0000000000000DCD·(3533)6768 0F4332···Uncompressed·Size···0000000000000D8D·(3469)
6769 0F433A···Compressed·Size·····0000000000000415·(1045)6769 0F433A···Compressed·Size·····00000000000003EA·(1002)
6770 0F4342·PAYLOAD6770 0F4342·PAYLOAD
  
6771 0F4757·LOCAL·HEADER·#283·····04034B50·(67324752)6771 0F472C·LOCAL·HEADER·#283·····04034B50·(67324752)
6772 0F475B·Extract·Zip·Spec······14·(20)·'2.0'6772 0F4730·Extract·Zip·Spec······14·(20)·'2.0'
6773 0F475C·Extract·OS············00·(0)·'MS-DOS'6773 0F4731·Extract·OS············00·(0)·'MS-DOS'
6774 0F475D·General·Purpose·Flag··0800·(2048)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 0F475F·Compression·Method····0008·(8)·'Deflated'6777 0F4734·Compression·Method····0008·(8)·'Deflated'
6778 0F4761·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980'6778 0F4736·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980'
6779 0F4765·CRC···················A438936D·(2755171181)6779 0F473A·CRC···················A2918A67·(2727447143)
6780 0F4769·Compressed·Size·······00004DAC·(19884)6780 0F473E·Compressed·Size·······00004E2E·(20014)
6781 0F476D·Uncompressed·Size·····00013F51·(81745)6781 0F4742·Uncompressed·Size·····00014157·(82263)
6782 0F4771·Filename·Length·······0010·(16)6782 0F4746·Filename·Length·······0010·(16)
6783 0F4773·Extra·Length··········0014·(20)6783 0F4748·Extra·Length··········0014·(20)
6784 0F4775·Filename··············'XXXXXXXXXXXXXXXX'6784 0F474A·Filename··············'XXXXXXXXXXXXXXXX'
6785 #6785 #
6786 #·WARNING:·Offset·0xF4775:·Filename·'XXXXXXXXXXXXXXXX'6786 #·WARNING:·Offset·0xF474A:·Filename·'XXXXXXXXXXXXXXXX'
6787 #··········Zero·length·filename6787 #··········Zero·length·filename
6788 #6788 #
6789 0F4785·Extra·ID·#1···········0001·(1)·'ZIP64'6789 0F475A·Extra·ID·#1···········0001·(1)·'ZIP64'
6790 0F4787···Length··············0010·(16)6790 0F475C···Length··············0010·(16)
6791 0F4789···Uncompressed·Size···0000000000013F51·(81745)6791 0F475E···Uncompressed·Size···0000000000014157·(82263)
6792 0F4791···Compressed·Size·····0000000000004DAC·(19884)6792 0F4766···Compressed·Size·····0000000000004E2E·(20014)
6793 0F4799·PAYLOAD6793 0F476E·PAYLOAD
  
6794 0F9545·LOCAL·HEADER·#284·····04034B50·(67324752)6794 0F959C·LOCAL·HEADER·#284·····04034B50·(67324752)
6795 0F9549·Extract·Zip·Spec······14·(20)·'2.0'6795 0F95A0·Extract·Zip·Spec······14·(20)·'2.0'
6796 0F954A·Extract·OS············00·(0)·'MS-DOS'6796 0F95A1·Extract·OS············00·(0)·'MS-DOS'
6797 0F954B·General·Purpose·Flag··0800·(2048)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 0F954D·Compression·Method····0008·(8)·'Deflated'6800 0F95A4·Compression·Method····0008·(8)·'Deflated'
6801 0F954F·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980'6801 0F95A6·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980'
6802 0F9553·CRC···················5FDEE6AE·(1608443566)6802 0F95AA·CRC···················4E40F4DE·(1312879838)
6803 0F9557·Compressed·Size·······0000055C·(1372)6803 0F95AE·Compressed·Size·······00000673·(1651)
6804 0F955B·Uncompressed·Size·····00001459·(5209)6804 0F95B2·Uncompressed·Size·····000017DF·(6111)
6805 0F955F·Filename·Length·······0012·(18)6805 0F95B6·Filename·Length·······0012·(18)
6806 0F9561·Extra·Length··········0014·(20)6806 0F95B8·Extra·Length··········0014·(20)
6807 0F9563·Filename··············'XXXXXXXXXXXXXXXXXX'6807 0F95BA·Filename··············'XXXXXXXXXXXXXXXXXX'
6808 #6808 #
6809 #·WARNING:·Offset·0xF9563:·Filename·'XXXXXXXXXXXXXXXXXX'6809 #·WARNING:·Offset·0xF95BA:·Filename·'XXXXXXXXXXXXXXXXXX'
6810 #··········Zero·length·filename6810 #··········Zero·length·filename
6811 #6811 #
6812 0F9575·Extra·ID·#1···········0001·(1)·'ZIP64'6812 0F95CC·Extra·ID·#1···········0001·(1)·'ZIP64'
6813 0F9577···Length··············0010·(16)6813 0F95CE···Length··············0010·(16)
6814 0F9579···Uncompressed·Size···0000000000001459·(5209)6814 0F95D0···Uncompressed·Size···00000000000017DF·(6111)
6815 0F9581···Compressed·Size·····000000000000055C·(1372)6815 0F95D8···Compressed·Size·····0000000000000673·(1651)
6816 0F9589·PAYLOAD6816 0F95E0·PAYLOAD
  
6817 0F9AE5·LOCAL·HEADER·#285·····04034B50·(67324752)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 0F9AE9·Extract·Zip·Spec······14·(20)·'2.0'6864 0FAE9A·Extract·Zip·Spec······14·(20)·'2.0'
6819 0F9AEA·Extract·OS············00·(0)·'MS-DOS'6865 0FAE9B·Extract·OS············00·(0)·'MS-DOS'
6820 0F9AEB·General·Purpose·Flag··0800·(2048)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 0F9AED·Compression·Method····0008·(8)·'Deflated'6869 0FAE9E·Compression·Method····0008·(8)·'Deflated'
6824 0F9AEF·Modification·Time·····00410000·(4259840)·'Fri·Feb··1·00:00:00·1980'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.
802 B
filelock/__init__.py
    
Offset 24, 15 lines modifiedOffset 24, 15 lines modified
24 ········AsyncReadWriteLock,24 ········AsyncReadWriteLock,
25 ····)25 ····)
26 ····from·._read_write·import·ReadWriteLock26 ····from·._read_write·import·ReadWriteLock
27 else:27 else:
28 ····try:28 ····try:
29 ········from·._async_read_write·import·AsyncAcquireReadWriteReturnProxy,·AsyncReadWriteLock29 ········from·._async_read_write·import·AsyncAcquireReadWriteReturnProxy,·AsyncReadWriteLock
30 ········from·._read_write·import·ReadWriteLock30 ········from·._read_write·import·ReadWriteLock
31 ····except·ImportError:··#·sqlite3·may·be·unavailable·if·Python·was·built·without·it·or·the·C·library·is·missing31 ····except·ImportError:··#·pragma:·lacks·sqlite3
32 ········AsyncAcquireReadWriteReturnProxy·=·None32 ········AsyncAcquireReadWriteReturnProxy·=·None
33 ········AsyncReadWriteLock·=·None33 ········AsyncReadWriteLock·=·None
34 ········ReadWriteLock·=·None34 ········ReadWriteLock·=·None
  
35 from·._soft·import·SoftFileLock35 from·._soft·import·SoftFileLock
36 from·._soft_rw·import·AsyncAcquireSoftReadWriteReturnProxy,·AsyncSoftReadWriteLock,·SoftReadWriteLock36 from·._soft_rw·import·AsyncAcquireSoftReadWriteReturnProxy,·AsyncSoftReadWriteLock,·SoftReadWriteLock
37 from·._strict·import·StrictSoftFileClaim,·StrictSoftFileClaimState,·StrictSoftFileLock37 from·._strict·import·StrictSoftFileClaim,·StrictSoftFileClaimState,·StrictSoftFileLock
23.6 KB
filelock/_api.py
    
Offset 392, 25 lines modifiedOffset 392, 25 lines modified
392 ········#·rejects·a·legitimate·reentrant·acquire;·the·unguarded·writes·to·the·WeakValueDictionary·are·a·data392 ········#·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·the394 ········#·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_construction402 ················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]·=·instance412 ················cls._instances[singleton_key]·=·instance
413 ················return·instance413 ················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 modifiedOffset 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 ····@classmethod638 ····@classmethod
639 ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children639 ····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·option643 ····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 modifiedOffset 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 ················raise968 ················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:·no·cover·-·exercised·in·fork·children973 ············return··#·pragma:·forked·child
974 ········#·A·finalizer·must·not·raise.·A·release·error·during·garbage·collection·would·otherwise·surface·as·an974 ········#·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·gets975 ········#·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 modifiedOffset 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·several1080 ········#·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 ············yield1084 ············yield
1085 ············return1085 ············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 ············yield1093 ············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·compatibility1096 ····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·file1098 ········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 modifiedOffset 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 ················raise1125 ················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:·no·cover·-·exercised·only·in·fork·children1129 ········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·=·None1133 ········self._context.pending_lock_file_fd·=·None
1134 ········self._context.pending_lock_file_fd_identity·=·None1134 ········self._context.pending_lock_file_fd_identity·=·None
1135 ········self._context.lock_file_fd·=·fd1135 ········self._context.lock_file_fd·=·fd
Offset 1143, 28 lines modifiedOffset 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·=·None1144 ········self._context.pending_lock_file_fd·=·None
1145 ········self._context.pending_lock_file_fd_identity·=·None1145 ········self._context.pending_lock_file_fd_identity·=·None
1146 ········self._context.lock_file_fd·=·None1146 ········self._context.lock_file_fd·=·None
1147 ········self._context.lock_file_fd_identity·=·None1147 ········self._context.lock_file_fd_identity·=·None
  
1148 ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children1148 ····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·=·None1152 ········self._context.claim_root·=·None
1153 ········self._context.lock_file_fd·=·None1153 ········self._context.lock_file_fd·=·None
1154 ········self._context.lock_file_fd_token·=·None1154 ········self._context.lock_file_fd_token·=·None
1155 ········self._context.lock_file_fd_identity·=·None1155 ········self._context.lock_file_fd_identity·=·None
1156 ········self._context.pending_lock_file_fd·=·None1156 ········self._context.pending_lock_file_fd·=·None
1157 ········self._context.pending_lock_file_fd_identity·=·None1157 ········self._context.pending_lock_file_fd_identity·=·None
1158 ········self._context.lock_counter·=·01158 ········self._context.lock_counter·=·0
1159 ········self._context.lock_file_key·=·None1159 ········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 modifiedOffset 1237, 18 lines modified
Max diff block lines reached; 16618/24156 bytes (68.79%) of diff not shown.
2.22 KB
filelock/_async.py
    
Offset 4, 15 lines modifiedOffset 4, 17 lines modified
  
4 import·asyncio4 import·asyncio
5 import·contextlib5 import·contextlib
6 import·time6 import·time
7 from·concurrent.futures·import·Future·as·ConcurrentFuture7 from·concurrent.futures·import·Future·as·ConcurrentFuture
8 from·dataclasses·import·dataclass8 from·dataclasses·import·dataclass
9 from·threading·import·Lock9 from·threading·import·Lock
10 from·typing·import·TYPE_CHECKING,·Final,·Generic,·TypeVar,·cast10 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,·Callable13 ····from·collections.abc·import·AsyncIterator,·Awaitable,·Callable
  
13 _T·=·TypeVar("_T")14 _T·=·TypeVar("_T")
  
  
Offset 135, 14 lines modifiedOffset 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·results140 ····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·cancellation155 ····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 modifiedOffset 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 ]
7.27 KB
filelock/_async_read_write.py
    
Offset 10, 25 lines modifiedOffset 10, 30 lines modified
10 from·contextlib·import·asynccontextmanager10 from·contextlib·import·asynccontextmanager
11 from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar11 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·_BackendOutcome,·_capture_call,·_drain_future,·_future_result,·_wait_until_done18 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·ReadWriteLock26 from·._read_write·import·ReadWriteLock
  
21 if·TYPE_CHECKING:27 if·TYPE_CHECKING:
22 ····from·collections.abc·import·AsyncGenerator,·Callable28 ····from·collections.abc·import·AsyncGenerator,·Callable
23 ····from·concurrent·import·futures29 ····from·concurrent·import·futures
24 ····from·types·import·TracebackType30 ····from·types·import·TracebackType
25 ····from·typing·import·NoReturn 
  
26 ····from·._api·import·AcquireReturnProxy31 ····from·._api·import·AcquireReturnProxy
  
27 _P·=·ParamSpec("_P")32 _P·=·ParamSpec("_P")
28 _R·=·TypeVar("_R")33 _R·=·TypeVar("_R")
  
  
Offset 70, 15 lines modifiedOffset 75, 15 lines modified
70 ········self._closed·=·False75 ········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·=·loop79 ············self._loop·=·loop
75 ············self._owns_executor·=·executor·is·None80 ············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:·no·cover·-·exercised·only·in·a·forked·constructor·callback82 ············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 ····@property85 ····@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_file88 ········return·self._lock.lock_file
Offset 207, 111 lines modifiedOffset 212, 103 lines modified
  
207 ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level212 ········: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 ············return217 ············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 ············return226 ············return
222 ········if·self._closed:227 ········if·self._closed:
223 ············return228 ············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·below235 ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below
231 ················self._raise_cancelled_error(cancellation,·error)236 ················_raise_cancelled_error(cancellation,·error)
232 ············self._closed·=·True237 ············self._closed·=·True
233 ············self._shutdown_owned_executor()238 ············self._shutdown_owned_executor()
234 ············raise239 ············raise
235 ········_future_result(close_future)240 ········_future_result(close_future)
236 ········self._closed·=·True241 ········self._closed·=·True
237 ········self._shutdown_owned_executor()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·below253 ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below
248 ················self._raise_cancelled_error(cancellation,·error)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·below257 ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below
252 ················self._raise_cancelled_error(cancellation,·error)258 ················_raise_cancelled_error(cancellation,·error)
253 ············raise259 ············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·below268 ············except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below
263 ················self._raise_cancelled_error(cancellation,·error)269 ················_raise_cancelled_error(cancellation,·error)
264 ············raise270 ············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.kwargs273 ········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.
2.08 KB
filelock/_error.py
    
Offset 8, 15 lines modifiedOffset 8, 15 lines modified
8 ········super().__init__()8 ········super().__init__()
9 ········self._lock_file·=·lock_file9 ········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·arg11 ········#·__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 ····@property17 ····@property
18 ····def·lock_file(self)·->·str:18 ····def·lock_file(self)·->·str:
Offset 37, 33 lines modifiedOffset 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_file38 ········self._lock_file·=·lock_file
39 ········self._claim_name·=·claim_name39 ········self._claim_name·=·claim_name
40 ········self._reason·=·reason40 ········self._reason·=·reason
41 ········super().__init__(self.__str__())41 ········super().__init__(self.__str__())
  
 42 ····def·__reduce__(
 43 ········self,
42 ····def·__reduce__(self)·->·tuple[type[SoftFileLockProtocolError],·tuple[str,·str·|·None,·str]]: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 ····@property49 ····@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_file52 ········return·self._lock_file
  
51 ····@property53 ····@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_name56 ········return·self._claim_name
  
55 ····@property57 ····@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._reason60 ········return·self._reason
  
  
59 __all__·=·[61 __all__·=·[
60 ····"LeaseSettingsMismatch",62 ····"LeaseSettingsMismatch",
61 ····"SoftFileLockLifetimeWarning",63 ····"SoftFileLockLifetimeWarning",
683 B
filelock/_identity.py
    
Offset 74, 15 lines modifiedOffset 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·None81 ················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.dwLowDateTime84 ········return·(creation.dwHighDateTime·<<·32)·|·creation.dwLowDateTime
  
85 else:··#·pragma:·win32·no·cover85 else:··#·pragma:·win32·no·cover
  
86 ····def·process_alive(pid:·int)·->·bool:86 ····def·process_alive(pid:·int)·->·bool:
12.1 KB
filelock/_lease.py
    
Offset 1, 15 lines modifiedOffset 1, 15 lines modified
1 from·__future__·import·annotations1 from·__future__·import·annotations
  
2 import·os2 import·os
3 import·secrets3 import·secrets
4 import·time4 import·time
5 from·contextlib·import·suppress5 from·contextlib·import·suppress
6 from·dataclasses·import·dataclass6 from·dataclasses·import·dataclass
7 from·threading·import·Event,·Thread,·current_thread7 from·threading·import·Event,·Thread,·current_thread,·local
8 from·typing·import·TYPE_CHECKING,·Literal8 from·typing·import·TYPE_CHECKING,·Literal
  
9 from·._error·import·LeaseSettingsMismatch9 from·._error·import·LeaseSettingsMismatch
10 from·._identity·import·owner_is_stale10 from·._identity·import·owner_is_stale
11 from·._marker·import·MarkerSoftFileLock,·OwnerMode,·OwnerRecord,·parse_marker11 from·._marker·import·MarkerSoftFileLock,·OwnerMode,·OwnerRecord,·parse_marker
12 from·._soft·import·_read_lock_file12 from·._soft·import·_read_lock_file
13 from·._util·import·break_lock_file,·touch13 from·._util·import·break_lock_file,·touch
Offset 36, 14 lines modifiedOffset 36, 45 lines modified
  
36 ····lock_file:·str36 ····lock_file:·str
37 ····token:·str37 ····token:·str
38 ····reason:·CompromiseReason38 ····reason:·CompromiseReason
39 ····error:·OSError·|·None·=·None39 ····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·every62 ····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.·Nothing63 ····``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·hint64 ····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 modifiedOffset 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_duration143 ········self._lease_duration·=·lease_duration
113 ········self._heartbeat_interval·=·heartbeat_interval144 ········self._heartbeat_interval·=·heartbeat_interval
114 ········self._on_compromise·=·on_compromise145 ········self._on_compromise·=·on_compromise
115 ········self._token:·str·|·None·=·None 
116 ········self._compromise:·LeaseCompromise·|·None·=·None 
117 ········self._heartbeat_stop·=·Event() 
118 ········self._heartbeat:·Thread·|·None·=·None146 ········#·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 ····@property154 ····@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_duration157 ········return·self._lease_duration
  
123 ····@property158 ····@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._token164 ········return·self._claim.token
  
130 ····@property165 ····@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·holds169 ········:returns:·the·:class:`LeaseCompromise`,·or·``None``·while·the·claim·still·holds
  
135 ········"""170 ········"""
136 ········return·self._compromise171 ········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·one174 ········self._stop_heartbeat()··#·no·earlier·claim's·heartbeat·outlives·the·acquisition·of·the·next·one
139 ········self._token·=·secrets.token_hex(16)175 ········claim.token·=·token·=·secrets.token_hex(16)
140 ········self._compromise·=·None176 ········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·just178 ········#·The·context·is·thread-local·by·default,·so·the·heartbeat·thread·cannot·read·the·descriptor·this·one·just
143 ········#·published.·Hand·it·the·fd·and·the·inode·it·verified·instead.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_identity181 ············identity·:=·self._context.lock_file_fd_identity
146 ········)·is·not·None:182 ········)·is·not·None:
147 ············self._start_heartbeat(fd,·identity,·self._token)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·=·None186 ········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.
12.4 KB
filelock/_read_write.py
    
Offset 57, 16 lines modifiedOffset 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·=·None58 ········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 ········with·self._lock: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·imports66 ················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).value68 ················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).value69 ················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·API70 ················if·increment_address·is·None·or·decrement_address·is·None:··#·pragma:·no·cover·-·resolved·CPython·API
Offset 74, 15 lines modifiedOffset 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._functions79 ············return·self._functions
  
80 ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children80 ····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 modifiedOffset 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_poisoned99 ············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_poisoned106 ················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 modifiedOffset 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·=·True118 ················self._sqlite_used·=·True
  
119 ····def·_reset_after_fork_in_child(self)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children119 ····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·=·False122 ········self._sqlite_used·=·False
  
123 ····@staticmethod123 ····@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 modifiedOffset 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·=·None149 ········connection._decrement_escrow·=·None
150 ········return·connection150 ········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 ················return154 ················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·=·None158 ····················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·=·functions166 ············increment,·decrement·=·functions
166 ············increment(self)167 ············increment(self)
167 ············self._decrement_escrow·=·decrement168 ············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 modifiedOffset 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:·no·cover·-·exercised·only·in·a·forked·constructor·callback205 ············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·instance208 ············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 modifiedOffset 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·instance236 ············return·instance
  
236 ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children237 ····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 modifiedOffset 414, 29 lines modified
Max diff block lines reached; 6428/12638 bytes (50.86%) of diff not shown.
4.14 KB
filelock/_soft.py
    
Offset 50, 15 lines modifiedOffset 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·open53 ········#·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_TRUNC55 ········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_nofollow57 ············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·cover63 ············):··#·pragma:·win32·no·cover
Offset 84, 15 lines modifiedOffset 84, 15 lines modified
84 ····················Path(self.lock_file).unlink()84 ····················Path(self.lock_file).unlink()
85 ············raise85 ············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 ················return91 ················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·and95 ················#·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 modifiedOffset 173, 22 lines modified
173 ················)173 ················)
174 ············raise174 ············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 ············return178 ············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.001186 ········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.·Recheck188 ············#·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 ····················return192 ····················return
Offset 211, 15 lines modifiedOffset 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·follow213 ····#·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·back214 ····#·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_ino218 ········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·FIFO219 ····#·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)
14.9 KB
filelock/_strict.py
    
Offset 1, 18 lines modifiedOffset 1, 19 lines modified
1 from·__future__·import·annotations1 from·__future__·import·annotations
  
2 import·contextlib2 import·contextlib
 3 import·errno
3 import·os4 import·os
4 import·secrets5 import·secrets
5 import·stat6 import·stat
6 import·sys7 import·sys
7 import·tempfile8 import·tempfile
8 import·time9 import·time
9 from·dataclasses·import·dataclass10 from·dataclasses·import·dataclass
10 from·errno·import·EACCES,·EEXIST,·ENOENT,·ENOSYS,·ENOTSUP,·EPERM,·ESTALE,·EXDEV11 from·errno·import·EACCES,·EEXIST,·ENOENT,·ENOSYS,·EPERM,·ESTALE,·EXDEV
11 from·pathlib·import·Path12 from·pathlib·import·Path
12 from·typing·import·TYPE_CHECKING,·Final,·Literal,·cast13 from·typing·import·TYPE_CHECKING,·Final,·Literal,·cast
  
13 from·._api·import·BaseFileLock,·_canonical,·_raise_cleanup_errors14 from·._api·import·BaseFileLock,·_canonical,·_raise_cleanup_errors
14 from·._error·import·SoftFileLockProtocolError15 from·._error·import·SoftFileLockProtocolError
15 from·._identity·import·host_name,·process_start_token16 from·._identity·import·host_name,·process_start_token
16 from·._soft_protocol·import·STRICT_SOFT_SENTINEL_RECORD17 from·._soft_protocol·import·STRICT_SOFT_SENTINEL_RECORD
Offset 74, 14 lines modifiedOffset 75, 27 lines modified
74 ········return·False75 ········return·False
75 ····return·True76 ····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·=·True89 ····_preserve_lock_file_supported:·bool·=·True
80 ····_on_acquired_supported:·bool·=·False90 ····_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·rule91 ····#:·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 modifiedOffset 151, 15 lines modified
137 ············return151 ············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 ················return156 ················return
143 ············raise157 ············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_error159 ············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·claims163 ············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 modifiedOffset 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 ············raise177 ············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_error181 ············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 modifiedOffset 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 ········if·(cleanup_error·:=·_unlink_in_directory(self._claim_directory,·claim_name))·is·not·None:207 ············cleanup_error·:=·_unlink_in_directory(self._claim_directory,·claim_name)
 208 ········)·is·not·None:··#·pragma:·needs·dir-fd
193 ············raise·cleanup_error209 ············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·pending211 ········#·_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·and212 ········#·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·each213 ········#·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 modifiedOffset 292, 15 lines modified
276 ····except·_PrivateRecordReclaimedError:292 ····except·_PrivateRecordReclaimedError:
277 ········return·None293 ········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 ············raise297 ············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_error300 ············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·None304 ········return·None
  
  
Offset 440, 35 lines modifiedOffset 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·None457 ····directory_fd·=·_open_directory(directory)·if·_OPEN_SUPPORTS_DIR_FD·else·None
442 ····directory_ref·=·directory,·directory_fd458 ····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·errors461 ····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·errors465 ········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 ········raise467 ········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.
909 B
filelock/_util.py
    
Offset 111, 15 lines modifiedOffset 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·the112 ····#·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·a114 ····#·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 ········return118 ········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·the120 #·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.
3.69 KB
filelock/_windows.py
    
Offset 154, 19 lines modifiedOffset 154, 21 lines modified
154 ········overlapped·=·_OVERLAPPED()··#·zero-initialized,·so·Offset/OffsetHigh/hEvent·are·0154 ········overlapped·=·_OVERLAPPED()··#·zero-initialized,·so·Offset/OffsetHigh/hEvent·are·0
155 ········flags·=·_LOCKFILE_EXCLUSIVE_LOCK·|·_LOCKFILE_FAIL_IMMEDIATELY155 ········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·True157 ············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·False160 ············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·used164 ········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·is171 ········Lock·file·cleanup:·Windows·attempts·to·delete·the·lock·file·after·release,·but·deletion·is
Offset 183, 15 lines modifiedOffset 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·again187 ················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 ················raise194 ················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·again196 ················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 modifiedOffset 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·None246 ················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·raising·anything·must·not·leak·the·handle262 ········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 ············raise264 ············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)``.
  
2.24 KB
filelock/asyncio.py
    
Offset 397, 15 lines modifiedOffset 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·below400 ················except·BaseException·as·error:··#·ruff:ignore[blind-except]··#·reported·with·the·cancellation·below
401 ····················rollback_error·=·error401 ····················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 modifiedOffset 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:·no·cover·-·exercised·in·fork·children678 ············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·None683 ················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 ················return685 ················return
422 B
filelock/version.py
    
Offset 14, 11 lines modifiedOffset 14, 11 lines modified
14 version:·str14 version:·str
15 __version__:·str15 __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·|·None18 commit_id:·str·|·None
19 __commit_id__:·str·|·None19 __commit_id__:·str·|·None
  
20 __version__·=·version·=·'3.31.0'20 __version__·=·version·=·'3.32.2'
21 __version_tuple__·=·version_tuple·=·(3,·31,·0)21 __version_tuple__·=·version_tuple·=·(3,·32,·2)
  
22 __commit_id__·=·commit_id·=·None22 __commit_id__·=·commit_id·=·None
5.53 KB
filelock/_soft_rw/_async.py
    
Offset 4, 21 lines modifiedOffset 4, 32 lines modified
  
4 import·asyncio4 import·asyncio
5 import·functools5 import·functools
6 import·os6 import·os
7 from·contextlib·import·asynccontextmanager7 from·contextlib·import·asynccontextmanager
8 from·typing·import·TYPE_CHECKING,·ParamSpec,·TypeVar8 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·SoftReadWriteLock17 from·._sync·import·SoftReadWriteLock
  
10 if·TYPE_CHECKING:18 if·TYPE_CHECKING:
11 ····from·collections.abc·import·AsyncGenerator,·Callable19 ····from·collections.abc·import·AsyncGenerator,·Callable
12 ····from·concurrent·import·futures20 ····from·concurrent·import·futures
13 ····from·types·import·TracebackType21 ····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 modifiedOffset 155, 15 lines modified
  
144 ········:raises·RuntimeError:·if·a·write·lock·is·already·held,·if·this·instance·was·invalidated·by155 ········:raises·RuntimeError:·if·a·write·lock·is·already·held,·if·this·instance·was·invalidated·by
145 ············:func:`os.fork`,·or·if·:meth:`close`·was·called156 ············:func:`os.fork`,·or·if·:meth:`close`·was·called
146 ········:raises·Timeout:·if·the·lock·cannot·be·acquired·within·*timeout*·seconds157 ········: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·=·None163 ········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 modifiedOffset 178, 15 lines modified
  
167 ········:raises·RuntimeError:·if·a·read·lock·is·already·held,·if·a·write·lock·is·held·by·a·different·thread,·if178 ········: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·called179 ············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*·seconds180 ········: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·level188 ········:param·force:·if·``True``,·release·the·lock·completely·regardless·of·the·current·lock·level
Offset 188, 21 lines modifiedOffset 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:·no·cover·-·exercised·only·in·fork·children204 ········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·await·loop.run_in_executor(self._executor,·functools.partial(func,·*args,·**kwargs))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·=·lock247 ········self.lock·=·lock
16.0 KB
filelock/_soft_rw/_sync.py
    
Offset 9, 15 lines modifiedOffset 9, 15 lines modified
9 import·secrets9 import·secrets
10 import·socket10 import·socket
11 import·stat11 import·stat
12 import·sys12 import·sys
13 import·threading13 import·threading
14 import·time14 import·time
15 import·uuid15 import·uuid
16 from·contextlib·import·contextmanager,·suppress16 from·contextlib·import·closing,·contextmanager,·suppress
17 from·dataclasses·import·dataclass17 from·dataclasses·import·dataclass
18 from·pathlib·import·Path18 from·pathlib·import·Path
19 from·typing·import·TYPE_CHECKING,·Final,·Literal19 from·typing·import·TYPE_CHECKING,·Final,·Literal
20 from·weakref·import·WeakValueDictionary20 from·weakref·import·WeakValueDictionary
  
21 from·filelock._api·import·(21 from·filelock._api·import·(
22 ····AcquireReturnProxy,22 ····AcquireReturnProxy,
Offset 78, 15 lines modifiedOffset 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 modifiedOffset 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]·=·instance105 ················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 modifiedOffset 209, 15 lines modified
209 ········self._closed:·bool·=·False209 ········self._closed:·bool·=·False
  
210 ········with·_ALL_INSTANCES_LOCK:210 ········with·_ALL_INSTANCES_LOCK:
211 ············_ALL_INSTANCES[id(self)]·=·self211 ············_ALL_INSTANCES[id(self)]·=·self
212 ········_register_fork_object(self)212 ········_register_fork_object(self)
  
213 ····@classmethod213 ····@classmethod
214 ····def·_reset_class_after_fork(cls)·->·None:··#·pragma:·no·cover·-·exercised·in·fork·children214 ····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·child215 ········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 ····@contextmanager220 ····@contextmanager
Offset 335, 28 lines modifiedOffset 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·raise338 ········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:·no·cover·-·exercised·only·in·fork·children341 ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child
342 ············return342 ············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 ················return346 ················return
347 ············self._closed·=·True347 ············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·=·None352 ····················self._readers_dir_fd_token·=·None
353 ····················fd,·self._readers_dir_fd·=·self._readers_dir_fd,·None353 ····················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·a359 ········When·the·lock·level·reaches·zero·the·heartbeat·thread·is·stopped·and·the·held·marker·file·is·unlinked.·On·a
Offset 364, 15 lines modifiedOffset 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·level365 ········: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:·no·cover·-·exercised·only·in·fork·children368 ········if·self._creator_pid·!=·os.getpid():··#·pragma:·forked·child
369 ············return369 ············return
370 ········with·self._locks.internal:370 ········with·self._locks.internal:
371 ············hold·=·self._hold371 ············hold·=·self._hold
372 ············if·hold·is·None:372 ············if·hold·is·None:
373 ················if·force:373 ················if·force:
374 ····················return374 ····················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 modifiedOffset 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:·no·cover·-·exercised·only·in·fork·children419 ········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·timeout422 ········timeout·=·self.timeout·if·timeout·is·None·else·timeout
423 ········blocking·=·self.blocking·if·blocking·is·None·else·blocking423 ········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 modifiedOffset 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.
355 B
soupsieve/__meta__.py
    
Offset 189, 9 lines modifiedOffset 189, 9 lines modified
  
189 ····#·Handle·post189 ····#·Handle·post
190 ····post·=·int(m.group('post'))·if·m.group('post')·else·0190 ····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,·0,·"final")192 __version_info__·=·Version(2,·9,·2,·"final")
193 __version__·=·__version_info__._get_canonical()193 __version__·=·__version_info__._get_canonical()
12.2 KB
soupsieve/css_parser.py
    
Offset 183, 14 lines modifiedOffset 183, 16 lines modified
183 #·Whitespace·checks183 #·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 #·Constants190 #·Constants
190 #·List·split·token191 #·List·split·token
191 COMMA_COMBINATOR·=·','192 COMMA_COMBINATOR·=·','
192 #·Relation·token·for·descendant193 #·Relation·token·for·descendant
193 WS_COMBINATOR·=·"·"194 WS_COMBINATOR·=·"·"
  
194 #·Parse·flags195 #·Parse·flags
Offset 250, 15 lines modifiedOffset 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)]·=·value255 ············custom_selectors[css_unescape(name)]·=·value
254 ····return·custom_selectors256 ····return·custom_selectors
  
  
255 def·css_unescape(content:·str,·string:·bool·=·False)·->·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 modifiedOffset 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·value280 ········return·value
  
279 ····return·(RE_CSS_ESC·if·not·string·else·RE_CSS_STR_ESC).sub(replace,·content)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 modifiedOffset 690, 18 lines modified
  
684 ········self.pattern·=·selector.replace('\x00',·'\ufffd')690 ········self.pattern·=·selector.replace('\x00',·'\ufffd')
685 ········self.flags·=·flags691 ········self.flags·=·flags
686 ········self.debug·=·self.flags·&·util.DEBUG692 ········self.debug·=·self.flags·&·util.DEBUG
687 ········self.custom·=·{}·if·custom·is·None·else·custom693 ········self.custom·=·{}·if·custom·is·None·else·custom
688 ········self.count·=·0694 ········self.count·=·0
  
689 ····def·check_count(self)·->·None: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·=·False702 ········inverse·=·False
Offset 711, 36 lines modifiedOffset 718, 38 lines modified
711 ········elif·util.lower(attr)·==·'type':718 ········elif·util.lower(attr)·==·'type':
712 ············flags·=·re.I·|·re.DOTALL719 ············flags·=·re.I·|·re.DOTALL
713 ············is_type·=·True720 ············is_type·=·True
714 ········else:721 ········else:
715 ············flags·=·re.DOTALL722 ············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 ················value·=·css_unescape(m.group('value'))724 ············value·=·css_unescape(m.group('value'))
  
721 ········if·not·op:725 ········if·not·op:
722 ············#·Attribute·name726 ············#·Attribute·name
723 ············pattern·=·None727 ············pattern·=·None
724 ········elif·op.startswith('^'):728 ········elif·op.startswith('^'):
725 ············#·Value·start·with729 ············#·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.*'·%·re.escape(value),·flags)732 ············pattern·=·re.compile(r'^%s.*'·%·value,·flags)
727 ········elif·op.startswith('$'):733 ········elif·op.startswith('$'):
728 ············#·Value·ends·with734 ············#·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$'·%·re.escape(value),·flags)737 ············pattern·=·re.compile(r'.*?%s$'·%·value,·flags)
730 ········elif·op.startswith('*'):738 ········elif·op.startswith('*'):
731 ············#·Value·contains739 ············#·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.*'·%·re.escape(value),·flags)742 ············pattern·=·re.compile(r'.*?%s.*'·%·value,·flags)
733 ········elif·op.startswith('~'):743 ········elif·op.startswith('~'):
734 ············#·Value·contains·word·within·space·separated·list744 ············#·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'[^\s\S]'·if·not·value·or·RE_WS.search(value)·else·re.escape(value)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·list749 ············#·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·matches752 ············#·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 modifiedOffset 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.flags805 ················selector,·custom=self.custom,·flags=self.flags
797 ············).process_selectors(flags=FLG_PSEUDO)806 ············).process_selectors(flags=FLG_PSEUDO)
798 ············self.custom[pseudo]·=·selector807 ············self.custom[pseudo]·=·selector
  
799 ········self.count·+=·selector.count808 ········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.
60.0 KB
svglib/svglib.py
    
Offset 18, 40 lines modifiedOffset 18, 52 lines modified
18 ········$·python·-m·svglib·foo.svg18 ········$·python·-m·svglib·foo.svg
19 """19 """
  
20 import·base6420 import·base64
21 import·copy21 import·copy
22 import·gzip22 import·gzip
23 import·itertools23 import·itertools
24 import·locale 
25 import·logging24 import·logging
26 import·os25 import·os
27 import·pathlib26 import·pathlib
28 import·re27 import·re
29 import·shlex28 import·shlex
30 import·shutil29 import·shutil
31 import·sys 
32 from·collections·import·defaultdict,·namedtuple30 from·collections·import·defaultdict,·namedtuple
33 from·io·import·BytesIO31 from·io·import·BytesIO
34 from·typing·import·Any,·BinaryIO,·Dict,·List,·Optional,·TextIO,·Tuple,·Union32 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·PILImage45 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·colors65 from·reportlab.lib·import·colors
54 from·reportlab.lib.units·import·toLength66 from·reportlab.lib.units·import·toLength
55 from·reportlab.pdfbase.pdfmetrics·import·stringWidth67 from·reportlab.pdfbase.pdfmetrics·import·stringWidth
Offset 89, 14 lines modifiedOffset 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.75105 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·has134 ····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·prevent135 ····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 modifiedOffset 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,·where279 ····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"]·=·0292 ············props["strokeWidth"]·=·0
246 ········if·"strokeColor"·in·props:293 ········if·"strokeColor"·in·props:
247 ············props["strokeColor"]·=·None294 ············props["strokeColor"]·=·None
248 ········return·props295 ········return·props
  
  
Max diff block lines reached; 57912/61426 bytes (94.28%) of diff not shown.
1.18 KB
filelock-3.31.0.dist-info/METADATA vs.
filelock-3.32.2.dist-info/METADATA
Files 96% similar despite different names
    
Offset 1, 10 lines modifiedOffset 1, 10 lines modified
1 Metadata-Version:·2.41 Metadata-Version:·2.4
2 Name:·filelock2 Name:·filelock
3 Version:·3.31.03 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.io5 Project-URL:·Documentation,·https://py-filelock.readthedocs.io
6 Project-URL:·Homepage,·https://github.com/tox-dev/py-filelock6 Project-URL:·Homepage,·https://github.com/tox-dev/py-filelock
7 Project-URL:·Source,·https://github.com/tox-dev/py-filelock7 Project-URL:·Source,·https://github.com/tox-dev/py-filelock
8 Project-URL:·Tracker,·https://github.com/tox-dev/py-filelock/issues8 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:·MIT10 License-Expression:·MIT
Offset 17, 14 lines modifiedOffset 17, 15 lines modified
17 Classifier:·Programming·Language·::·Python17 Classifier:·Programming·Language·::·Python
18 Classifier:·Programming·Language·::·Python·::·3·::·Only18 Classifier:·Programming·Language·::·Python·::·3·::·Only
19 Classifier:·Programming·Language·::·Python·::·3.1019 Classifier:·Programming·Language·::·Python·::·3.10
20 Classifier:·Programming·Language·::·Python·::·3.1120 Classifier:·Programming·Language·::·Python·::·3.11
21 Classifier:·Programming·Language·::·Python·::·3.1221 Classifier:·Programming·Language·::·Python·::·3.12
22 Classifier:·Programming·Language·::·Python·::·3.1322 Classifier:·Programming·Language·::·Python·::·3.13
23 Classifier:·Programming·Language·::·Python·::·3.1423 Classifier:·Programming·Language·::·Python·::·3.14
 24 Classifier:·Programming·Language·::·Python·::·3.15
24 Classifier:·Topic·::·Internet25 Classifier:·Topic·::·Internet
25 Classifier:·Topic·::·Software·Development·::·Libraries26 Classifier:·Topic·::·Software·Development·::·Libraries
26 Classifier:·Topic·::·System27 Classifier:·Topic·::·System
27 Requires-Python:·>=3.1028 Requires-Python:·>=3.10
28 Description-Content-Type:·text/markdown29 Description-Content-Type:·text/markdown
  
29 #·filelock30 #·filelock
123 B
filelock-3.31.0.dist-info/licenses/LICENSE vs.
filelock-3.32.2.dist-info/licenses/LICENSE
Files identical despite different names
536 B
soupsieve-2.9.dist-info/METADATA vs.
soupsieve-2.9.2.dist-info/METADATA
Files 99% similar despite different names
    
Offset 1, 10 lines modifiedOffset 1, 10 lines modified
1 Metadata-Version:·2.41 Metadata-Version:·2.4
2 Name:·soupsieve2 Name:·soupsieve
3 Version:·2.93 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/soupsieve5 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:·MIT7 License-Expression:·MIT
8 License-File:·LICENSE.md8 License-File:·LICENSE.md
9 Keywords:·CSS,HTML,XML,filter,query,selector,soup9 Keywords:·CSS,HTML,XML,filter,query,selector,soup
10 Classifier:·Development·Status·::·5·-·Production/Stable10 Classifier:·Development·Status·::·5·-·Production/Stable
127 B
soupsieve-2.9.dist-info/licenses/LICENSE.md vs.
soupsieve-2.9.2.dist-info/licenses/LICENSE.md
Files identical despite different names
1.81 KB
svglib-2.0.2.dist-info/METADATA vs.
svglib-2.1.0.dist-info/METADATA
Files 98% similar despite different names
    
Offset 1, 10 lines modifiedOffset 1, 10 lines modified
1 Metadata-Version:·2.41 Metadata-Version:·2.4
2 Name:·svglib2 Name:·svglib
3 Version:·2.0.23 Version:·2.1.0
4 Summary:·A·pure-Python·library·for·reading·and·converting·SVG4 Summary:·A·pure-Python·library·for·reading·and·converting·SVG
5 Project-URL:·Homepage,·https://github.com/deeplook/svglib5 Project-URL:·Homepage,·https://github.com/deeplook/svglib
6 Author:·Dinu·Gherman6 Author:·Dinu·Gherman
7 License-Expression:·LGPL-3.0-or-later7 License-Expression:·LGPL-3.0-or-later
8 License-File:·LICENSE.txt8 License-File:·LICENSE.txt
9 Keywords:·PDF,SVG,conversion,graphics,reportlab9 Keywords:·PDF,SVG,conversion,graphics,reportlab
10 Classifier:·Development·Status·::·5·-·Production/Stable10 Classifier:·Development·Status·::·5·-·Production/Stable
Offset 19, 14 lines modifiedOffset 19, 15 lines modified
19 Classifier:·Programming·Language·::·Python19 Classifier:·Programming·Language·::·Python
20 Classifier:·Programming·Language·::·Python·::·3·::·Only20 Classifier:·Programming·Language·::·Python·::·3·::·Only
21 Classifier:·Programming·Language·::·Python·::·3.921 Classifier:·Programming·Language·::·Python·::·3.9
22 Classifier:·Programming·Language·::·Python·::·3.1022 Classifier:·Programming·Language·::·Python·::·3.10
23 Classifier:·Programming·Language·::·Python·::·3.1123 Classifier:·Programming·Language·::·Python·::·3.11
24 Classifier:·Programming·Language·::·Python·::·3.1224 Classifier:·Programming·Language·::·Python·::·3.12
25 Classifier:·Programming·Language·::·Python·::·3.1325 Classifier:·Programming·Language·::·Python·::·3.13
 26 Classifier:·Programming·Language·::·Python·::·3.14
26 Classifier:·Topic·::·Documentation27 Classifier:·Topic·::·Documentation
27 Classifier:·Topic·::·Multimedia·::·Graphics·::·Graphics·Conversion28 Classifier:·Topic·::·Multimedia·::·Graphics·::·Graphics·Conversion
28 Classifier:·Topic·::·Printing29 Classifier:·Topic·::·Printing
29 Classifier:·Topic·::·Software·Development·::·Libraries·::·Python·Modules30 Classifier:·Topic·::·Software·Development·::·Libraries·::·Python·Modules
30 Classifier:·Topic·::·Text·Processing·::·Markup·::·XML31 Classifier:·Topic·::·Text·Processing·::·Markup·::·XML
31 Classifier:·Topic·::·Utilities32 Classifier:·Topic·::·Utilities
32 Requires-Python:·>=3.933 Requires-Python:·>=3.9
Offset 94, 15 lines modifiedOffset 95, 17 lines modified
94 -·support·Python·3.9+·and·PyPy395 -·support·Python·3.9+·and·PyPy3
  
  
95 ##·Known·limitations96 ##·Known·limitations
  
96 -·`@import`·rules·in·stylesheets·are·ignored.·CSS·is·supported,·but·the·range97 -·`@import`·rules·in·stylesheets·are·ignored.·CSS·is·supported,·but·the·range
97 ··of·supported·attributes·is·still·limited98 ··of·supported·attributes·is·still·limited
98 -·clipping·is·limited·to·single·paths,·no·mask·support99 -·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 ##·Examples103 ##·Examples
  
101 You·can·use·`svglib`·as·a·Python·package·e.g.·like·in·the·following104 You·can·use·`svglib`·as·a·Python·package·e.g.·like·in·the·following
102 interactive·Python·session:105 interactive·Python·session:
125 B
svglib-2.0.2.dist-info/licenses/LICENSE.txt vs.
svglib-2.1.0.dist-info/licenses/LICENSE.txt
Files identical despite different names
1.34 KB
assets/chaquopy/build.json
1.29 KB
Pretty-printed
Similarity: 0.99822695035461% Differences: {"'assets'": "{'requirements-common.imy': 'f8faa1929931e750581957471fea992351ff676d'}"}
    
Offset 37, 15 lines modifiedOffset 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":·"6be8d5f2968052ad123196de636dbf444dc7e0f0",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":·[