angr 9.2.108__py3-none-manylinux2014_aarch64.whl → 9.2.110__py3-none-manylinux2014_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of angr might be problematic. Click here for more details.

angr/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylint: disable=wildcard-import
2
2
  # pylint: disable=wrong-import-position
3
3
 
4
- __version__ = "9.2.108"
4
+ __version__ = "9.2.110"
5
5
 
6
6
  if bytes is str:
7
7
  raise Exception(
@@ -36,12 +36,6 @@ loggers = Loggers()
36
36
  del Loggers
37
37
  del logging
38
38
 
39
- # import hook: pkg_resources is too slow to import, but it is used by some other packages that angr depends on. while
40
- # we upstream our fixes, we replace it with a light-weight solution.
41
- from .misc.import_hooks import import_fake_pkg_resources
42
-
43
- import_fake_pkg_resources(force=False)
44
-
45
39
  # this must happen first, prior to initializing analyses
46
40
  from .sim_procedure import SimProcedure
47
41
  from .procedures import SIM_PROCEDURES, SimProcedures, SIM_LIBRARIES, SIM_TYPE_COLLECTIONS
@@ -2181,7 +2181,7 @@ class Reassembler(Analysis):
2181
2181
  )
2182
2182
  all_assembly_lines.append(data.assembly(comments=comments, symbolized=symbolized))
2183
2183
 
2184
- s = "\n".join(all_assembly_lines)
2184
+ s += "\n".join(all_assembly_lines)
2185
2185
 
2186
2186
  return s
2187
2187
 
@@ -72,6 +72,12 @@ class SimEngineLightMixin:
72
72
  return 0
73
73
  elif isinstance(spoffset_expr.args[1], claripy.ast.Base) and spoffset_expr.args[1].op == "BVV":
74
74
  return spoffset_expr.args[1].args[0]
75
+ elif spoffset_expr.op == "__sub__":
76
+ if len(spoffset_expr.args) == 1:
77
+ # Unexpected but fine
78
+ return 0
79
+ elif isinstance(spoffset_expr.args[1], claripy.ast.Base) and spoffset_expr.args[1].op == "BVV":
80
+ return spoffset_expr.args[1].args[0] & ((1 << spoffset_expr.size()) - 1)
75
81
  return None
76
82
 
77
83
 
@@ -121,6 +121,18 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
121
121
  self.state.scratch.bbl_addr = addr
122
122
 
123
123
  while True:
124
+ # check permissions, are we allowed to execute here? Do we care?
125
+ if o.STRICT_PAGE_ACCESS in self.state.options:
126
+ try:
127
+ perms = self.state.memory.permissions(addr)
128
+ except errors.SimMemoryError as sim_mem_err:
129
+ raise errors.SimSegfaultError(addr, "exec-miss") from sim_mem_err
130
+ else:
131
+ if not self.state.solver.symbolic(perms):
132
+ perms = self.state.solver.eval(perms)
133
+ if not perms & 4 and o.ENABLE_NX in self.state.options:
134
+ raise errors.SimSegfaultError(addr, "non-executable")
135
+
124
136
  if irsb is None:
125
137
  irsb = self.lift_vex(
126
138
  addr=addr,
@@ -148,18 +160,6 @@ class HeavyVEXMixin(SuccessorsMixin, ClaripyDataMixin, SimStateStorageMixin, VEX
148
160
  if irsb.size == 0:
149
161
  raise errors.SimIRSBError("Empty IRSB passed to HeavyVEXMixin.")
150
162
 
151
- # check permissions, are we allowed to execute here? Do we care?
152
- if o.STRICT_PAGE_ACCESS in self.state.options:
153
- try:
154
- perms = self.state.memory.permissions(addr)
155
- except errors.SimMemoryError as sim_mem_err:
156
- raise errors.SimSegfaultError(addr, "exec-miss") from sim_mem_err
157
- else:
158
- if not self.state.solver.symbolic(perms):
159
- perms = self.state.solver.eval(perms)
160
- if not perms & 4 and o.ENABLE_NX in self.state.options:
161
- raise errors.SimSegfaultError(addr, "non-executable")
162
-
163
163
  self.state.scratch.set_tyenv(irsb.tyenv)
164
164
  self.state.scratch.irsb = irsb
165
165
 
angr/misc/bug_report.py CHANGED
@@ -1,11 +1,10 @@
1
- import importlib
1
+ import importlib.metadata
2
2
  import os
3
3
  import sys
4
4
  import datetime
5
5
  import gc
6
6
  import ctypes
7
-
8
- from .import_hooks import remove_fake_pkg_resources
7
+ import sysconfig
9
8
 
10
9
 
11
10
  have_gitpython = False
@@ -34,10 +33,6 @@ def get_venv():
34
33
 
35
34
 
36
35
  def print_versions():
37
- remove_fake_pkg_resources()
38
- # import the real pkg_resources
39
- import pkg_resources # pylint:disable=import-outside-toplevel
40
-
41
36
  for m in angr_modules:
42
37
  print("######## %s #########" % m)
43
38
  try:
@@ -50,7 +45,7 @@ def print_versions():
50
45
  print("Python found it in %s" % (python_filename))
51
46
  try:
52
47
  pip_package = python_packages.get(m, m)
53
- pip_version = pkg_resources.get_distribution(pip_package)
48
+ pip_version = importlib.metadata.version(pip_package)
54
49
  print("Pip version %s" % pip_version)
55
50
  except Exception: # pylint: disable-broad-except
56
51
  print("Pip version not found!")
@@ -83,11 +78,7 @@ def print_git_info(dirname):
83
78
 
84
79
 
85
80
  def print_system_info():
86
- remove_fake_pkg_resources()
87
- # import the real pkg_resources
88
- import pkg_resources # pylint:disable=import-outside-toplevel
89
-
90
- print("Platform: " + pkg_resources.get_build_platform())
81
+ print("Platform: " + sysconfig.get_platform())
91
82
  print("Python version: " + str(sys.version))
92
83
 
93
84
 
@@ -1,9 +1,9 @@
1
1
  import binascii
2
2
  import copy
3
3
  import ctypes
4
+ import importlib.resources
4
5
  import itertools
5
6
  import logging
6
- import os
7
7
  import sys
8
8
  import threading
9
9
  import time
@@ -392,23 +392,6 @@ class _VexArchInfo(ctypes.Structure):
392
392
  ]
393
393
 
394
394
 
395
- def _locate_lib(module: str, library: str) -> str:
396
- """
397
- Attempt to find a native library without using pkg_resources, and only fall back to pkg_resources upon failures.
398
- This is because "import pkg_resources" is slow.
399
-
400
- :return: The full path of the native library.
401
- """
402
- base_dir = os.path.join(os.path.dirname(__file__), "..")
403
- attempt = os.path.join(base_dir, library)
404
- if os.path.isfile(attempt):
405
- return attempt
406
-
407
- import pkg_resources # pylint:disable=import-outside-toplevel
408
-
409
- return pkg_resources.resource_filename(module, os.path.join(library))
410
-
411
-
412
395
  def _load_native():
413
396
  if sys.platform == "darwin":
414
397
  libfile = "angr_native.dylib"
@@ -418,7 +401,7 @@ def _load_native():
418
401
  libfile = "angr_native.so"
419
402
 
420
403
  try:
421
- angr_path = _locate_lib("angr", os.path.join("lib", libfile))
404
+ angr_path = str(importlib.resources.files("angr") / "lib" / libfile)
422
405
  h = ctypes.CDLL(angr_path)
423
406
 
424
407
  VexArch = ctypes.c_int
@@ -134,7 +134,7 @@ class ListPage(MemoryObjectMixin, PageBase):
134
134
  merged_offsets = set()
135
135
  for b in sorted(changed_offsets):
136
136
  if merged_to is not None and not b >= merged_to:
137
- l.info("merged_to = %d ... already merged byte 0x%x", merged_to, b)
137
+ l.debug("merged_to = %d ... already merged byte 0x%x", merged_to, b)
138
138
  continue
139
139
  l.debug("... on byte 0x%x", b)
140
140
 
@@ -145,10 +145,10 @@ class ListPage(MemoryObjectMixin, PageBase):
145
145
  # all memories that don't have those bytes
146
146
  for sm, fv in zip(all_pages, merge_conditions):
147
147
  if sm._contains(b, page_addr):
148
- l.info("... present in %s", fv)
148
+ l.debug("... present in %s", fv)
149
149
  memory_objects.append((sm.content[b], fv))
150
150
  else:
151
- l.info("... not present in %s", fv)
151
+ l.debug("... not present in %s", fv)
152
152
  unconstrained_in.append((sm, fv))
153
153
 
154
154
  mos = {mo for mo, _ in memory_objects}
@@ -207,7 +207,7 @@ class ListPage(MemoryObjectMixin, PageBase):
207
207
  min_size = i
208
208
  break
209
209
  merged_to = b + min_size
210
- l.info("... determined minimum size of %d", min_size)
210
+ l.debug("... determined minimum size of %d", min_size)
211
211
 
212
212
  # Now, we have the minimum size. We'll extract/create expressions of that
213
213
  # size and merge them
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: angr
3
- Version: 9.2.108
3
+ Version: 9.2.110
4
4
  Summary: A multi-architecture binary analysis toolkit, with the ability to perform dynamic symbolic execution and various static analyses on binaries
5
5
  Home-page: https://github.com/angr/angr
6
6
  License: BSD-2-Clause
@@ -15,13 +15,13 @@ Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: CppHeaderParser
17
17
  Requires-Dist: GitPython
18
- Requires-Dist: ailment ==9.2.108
19
- Requires-Dist: archinfo ==9.2.108
18
+ Requires-Dist: ailment ==9.2.110
19
+ Requires-Dist: archinfo ==9.2.110
20
20
  Requires-Dist: cachetools
21
21
  Requires-Dist: capstone ==5.0.0.post1
22
22
  Requires-Dist: cffi >=1.14.0
23
- Requires-Dist: claripy ==9.2.108
24
- Requires-Dist: cle ==9.2.108
23
+ Requires-Dist: claripy ==9.2.110
24
+ Requires-Dist: cle ==9.2.110
25
25
  Requires-Dist: dpkt
26
26
  Requires-Dist: itanium-demangler
27
27
  Requires-Dist: mulpyplexer
@@ -31,7 +31,7 @@ Requires-Dist: protobuf >=3.19.0
31
31
  Requires-Dist: psutil
32
32
  Requires-Dist: pycparser >=2.18
33
33
  Requires-Dist: pyformlang
34
- Requires-Dist: pyvex ==9.2.108
34
+ Requires-Dist: pyvex ==9.2.110
35
35
  Requires-Dist: rich >=13.1.0
36
36
  Requires-Dist: rpyc
37
37
  Requires-Dist: sortedcontainers
@@ -1,4 +1,4 @@
1
- angr/__init__.py,sha256=Np1bbynJj6IncpMFfeb-y9r7uYU2trMoZpEFugh_tkY,3993
1
+ angr/__init__.py,sha256=14LIEmrBPgRxAc3zB4BOctrpwlqOlijIq8zd2lEdqeM,3708
2
2
  angr/__main__.py,sha256=kaO56Te6h73SM94BVtASF00q5QbBbC3eBs9poVc9sVI,1887
3
3
  angr/annocfg.py,sha256=1tnBfxgLJh9I6Brm1JDdsWLHGmCQYdD6PTC_bFTOMrg,10775
4
4
  angr/blade.py,sha256=B8QXVQ93jz1YCIlb-dZLeBqYmVFdMXI5GleP1Wnxjrw,15519
@@ -50,7 +50,7 @@ angr/analyses/init_finder.py,sha256=hFHPsHipF4QkWzVqcDeTgL6YIaYi8bAyaURZBksS4KI,
50
50
  angr/analyses/loop_analysis.py,sha256=nIbDIzvys-FRtJYnoZYNbMWH5V88qrhoMtrMRCTbkLY,9412
51
51
  angr/analyses/loopfinder.py,sha256=X8F4Dcu2UHDXt6JifK6EfROAeeczyca6V7zxx9z7GpQ,7122
52
52
  angr/analyses/proximity_graph.py,sha256=TEgEYMnZgjV9oWUS3mIteftrGeFJCqMkeDUHy38NBq8,16260
53
- angr/analyses/reassembler.py,sha256=TCMyiW1IrKIuNaZCVRARwHpN39GHYDKaH5O3FsSmKlE,100412
53
+ angr/analyses/reassembler.py,sha256=U1suz3TwZI2jopzPXNenxa1uFD2aB3JVS-M8yIWX-lc,100413
54
54
  angr/analyses/soot_class_hierarchy.py,sha256=Cs_LRV1RLXH6sF_E49tJWg9Inxvv_o5mB-VaIBcbQJg,8941
55
55
  angr/analyses/stack_pointer_tracker.py,sha256=9TOGwz5Rx4jXxoGbdtrBrMca6mJi3SXn4MS4Gx-vrmk,30207
56
56
  angr/analyses/static_hooker.py,sha256=g57k_fwxgS4oTzslyCpOf4faG17E685a4-4SpEz8Ges,1711
@@ -337,7 +337,7 @@ angr/engines/syscall.py,sha256=LNMC3zyis3OiWC7_8Zn1blMw1EDib5FjUqepXlaWDTI,2177
337
337
  angr/engines/unicorn.py,sha256=gf7LjjWyaaujqSuCq3d-BGm8t5sdZjzsJeBevGfdiLw,24447
338
338
  angr/engines/light/__init__.py,sha256=j9vH2fU9MaNVQ8NT3Ek3Tj2zkGlVxlKyzia8zVTofYs,186
339
339
  angr/engines/light/data.py,sha256=jZBAJxor2zg5m4s63joSrjUs8H-OeHBZiqZmc3dqEQQ,23132
340
- angr/engines/light/engine.py,sha256=3wnoEdGbnoipaG9I1gkHQ5SVD_4KTLHVpx6FuaQ9piI,45095
340
+ angr/engines/light/engine.py,sha256=m35I-_5Gg9Uwety6ex8BEfNf5Ga9GD2UHRK8K1XBFD0,45468
341
341
  angr/engines/pcode/__init__.py,sha256=UwMEwXQvHXIIgedJn2ZOvBBEgfHg2rfREBSpcTSXCZ4,83
342
342
  angr/engines/pcode/behavior.py,sha256=BuzA_nX_ebuFiGgup7aJ-bgD9KmUR2dPSGUM51MKxOM,29290
343
343
  angr/engines/pcode/cc.py,sha256=CUKkivYUddt8McAYLwAPO5btzDHwO65yBQvWs3CV9dU,3085
@@ -399,7 +399,7 @@ angr/engines/vex/heavy/__init__.py,sha256=VapnI5PnxNnZyqtmQpJNrRs9Yh01-gpfR1LjaG
399
399
  angr/engines/vex/heavy/actions.py,sha256=f8CbzwIOSgksmiY5nwDlgAomOI88wa5S_4vk5RE5718,8871
400
400
  angr/engines/vex/heavy/concretizers.py,sha256=bwv8VIqwS2DGP3qf_EI4Kb97_Ma8wygbnn-0HWsTfo0,14702
401
401
  angr/engines/vex/heavy/dirty.py,sha256=a4rWD03dA9m7HoLM8-TBMxFptkyRNVPWg8OOAiar-Cg,18699
402
- angr/engines/vex/heavy/heavy.py,sha256=ZDRxpH1V3396MuyofLFbyy_cgAoljkWXEBR5Mr_nYRE,15822
402
+ angr/engines/vex/heavy/heavy.py,sha256=mr_k23ykI8NV3SwqeNzKTDtJr_9n6nIIFNMII5ThbOU,15822
403
403
  angr/engines/vex/heavy/inspect.py,sha256=NNQpo4E267W8Z0RDQee9gGH9KDx0mydwjVo02yogT6o,2317
404
404
  angr/engines/vex/heavy/resilience.py,sha256=4TYoIFjIygSwRsu4229CsbRNOtlP-QQuligWZRKlEjQ,3737
405
405
  angr/engines/vex/heavy/super_fastpath.py,sha256=2E1Tdai9Xf7g-wf5AD3FrLN67pVusnQtF1aPRLLNxEg,1180
@@ -493,9 +493,8 @@ angr/lib/angr_native.so,sha256=EBaC0qxpIeDPBs6VHUtYJeVevooW9nHI3TO6ncy0KR8,23083
493
493
  angr/misc/__init__.py,sha256=Ct-Q6-c-Frdz5Ihkqmou3j_1jyJi8WJXlQxs-gPQg0Y,237
494
494
  angr/misc/ansi.py,sha256=m5RY65yyvluUJErkvCF4I4z1o5kXi2xb3Yuvt9bITCA,776
495
495
  angr/misc/autoimport.py,sha256=vSXclz6pss3lMecoT5_doX0SvORNmZPIvVyDm4je4HE,3419
496
- angr/misc/bug_report.py,sha256=JJ0IkN9-VAjqJjdfNaSNlV5GqRyu-B9gus3WA1WnLbQ,4241
496
+ angr/misc/bug_report.py,sha256=83AsIgUVhE1rZO0mQPO6h5VDYRyBq1Wv1CjQAxJ04ME,3928
497
497
  angr/misc/hookset.py,sha256=TzhmQYf7BP6fHKXYu_1tHalrHAmP4IVmVkh_Hlp8fS8,4486
498
- angr/misc/import_hooks.py,sha256=SpcB3ML_1HTO3JeGVsAD6GFEpxy2C4EMpLzH9zSq8Xo,1943
499
498
  angr/misc/loggers.py,sha256=m3BZ0WFL14qmYZiGgGKKJ31tLnO5x2BV4UmqD2606wc,4225
500
499
  angr/misc/picklable_lock.py,sha256=IZ9sk7MTvDXtX7EDWEBRwGEn_DNqfsTlzFcMCodnjUk,1276
501
500
  angr/misc/plugins.py,sha256=W5P5wwxo42ThYXOl9yTlbO-qYr-WrxIf8i7jy-ohra4,9339
@@ -1211,7 +1210,7 @@ angr/state_plugins/solver.py,sha256=HrEQgqNJtzdB8I8Qu8XG_3LjMBt6OdbAIewUFZiNZHk,
1211
1210
  angr/state_plugins/symbolizer.py,sha256=3UAfStON-0GuuHhkD4JD6Y5WveqEfTD3JLK3uj0R-co,11039
1212
1211
  angr/state_plugins/trace_additions.py,sha256=LRcgdGKY2QtzOwsVa-FYLGRFcl0ISOnq-WzCMayiM-8,30091
1213
1212
  angr/state_plugins/uc_manager.py,sha256=9yEE10rrGXTVncLzVOpgvSAGA2RdzApUu_fq_lUksDs,2643
1214
- angr/state_plugins/unicorn_engine.py,sha256=till_XsE5yEL9BbdVnxi0PK_kJ6sAF0oYwh1d0zC138,78095
1213
+ angr/state_plugins/unicorn_engine.py,sha256=EHaP64FofZe3Kl_tdeDRzQWfoTp7j8_K1b3exkLZmLU,77522
1215
1214
  angr/state_plugins/view.py,sha256=4gUiyQM2IPZ2rn91yNKN9CQp662XzdigSeGdVQ5lOFM,12361
1216
1215
  angr/state_plugins/heap/__init__.py,sha256=uyxW6BfOmiuhbIYIjXMDQW8AxfN9scC2bwRdsSAiajk,136
1217
1216
  angr/state_plugins/heap/heap_base.py,sha256=qtonZCTiGSh30UbPZ92ILXRVmO3pV4NZyDPN0DB8QvI,6229
@@ -1261,7 +1260,7 @@ angr/storage/memory_mixins/paged_memory/pages/__init__.py,sha256=rwGAcESljLORCDt
1261
1260
  angr/storage/memory_mixins/paged_memory/pages/cooperation.py,sha256=3FTR6Ksqn8Vg3QvvyMNs_6EvwgFVi_xvYxId7hR_ZZw,12726
1262
1261
  angr/storage/memory_mixins/paged_memory/pages/history_tracking_mixin.py,sha256=P5ORlm26_7v--hNcxDwLzZGTRwcLcaHzKModa5yoUPA,3003
1263
1262
  angr/storage/memory_mixins/paged_memory/pages/ispo_mixin.py,sha256=mHt5nQYXkXifwGT0_UGvKirECEC2v7jNNtf_6oY57uI,2050
1264
- angr/storage/memory_mixins/paged_memory/pages/list_page.py,sha256=LCTURmDCtAtBrvaCjwaMSXgT-gfAhP22t8TEx2L0L7E,14580
1263
+ angr/storage/memory_mixins/paged_memory/pages/list_page.py,sha256=FJhqPdF0fFkktIfUKaVZoDxD5jW7qwugn6US2yctcrc,14584
1265
1264
  angr/storage/memory_mixins/paged_memory/pages/multi_values.py,sha256=hW-8svWpMJj4q6GVnW5JqDAp-2riFS5PnE7B_FXEIEw,11289
1266
1265
  angr/storage/memory_mixins/paged_memory/pages/mv_list_page.py,sha256=7pAL_YxTNEx1d7qTpJqrXIRKMB04SN4ASwz6vfyBbCk,17671
1267
1266
  angr/storage/memory_mixins/paged_memory/pages/permissions_mixin.py,sha256=Ek2YSmFOGUScFXPx8hqroNkl3gK1aqKCMv_X3_pImLs,830
@@ -1293,9 +1292,9 @@ angr/utils/mp.py,sha256=cv_NeysxLgyCdE-Euefnfv078ia5maHSnUn9f23zz88,1882
1293
1292
  angr/utils/segment_list.py,sha256=5nnuVtdZk9NS2y_xUBVA9khWPueP_zagNtPSjaoMHbA,20410
1294
1293
  angr/utils/timing.py,sha256=uOowCP8kotDrKDOjlAod-guBuYkAA8zEtiAwpdwMlIU,1334
1295
1294
  angr/utils/typing.py,sha256=pCjA7JZAzcvrk-iyIE2cRHc1G66AMSGEON3aFfjtPVc,431
1296
- angr-9.2.108.dist-info/LICENSE,sha256=cgL_ho5B1NH8UxwtBuqThRWdjear8b7hktycaS1sz6g,1327
1297
- angr-9.2.108.dist-info/METADATA,sha256=dSCQ-Cvn8ZiWAoqMc2ZbMbVZfynQLsoOGV361_goSUg,4703
1298
- angr-9.2.108.dist-info/WHEEL,sha256=rio9sx7gb11-P9V0RSwFnwh2SO_5Jwt7bTXt6VcIvKE,109
1299
- angr-9.2.108.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1300
- angr-9.2.108.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1301
- angr-9.2.108.dist-info/RECORD,,
1295
+ angr-9.2.110.dist-info/LICENSE,sha256=cgL_ho5B1NH8UxwtBuqThRWdjear8b7hktycaS1sz6g,1327
1296
+ angr-9.2.110.dist-info/METADATA,sha256=VR7ifRHytmqNvvyJfk_CZKTWRupdmP-iWDKKLlUMwf4,4703
1297
+ angr-9.2.110.dist-info/WHEEL,sha256=1JCkHlL-9BC7wYtc7btakW2f7cT4qSTuxeFG2BKpg5w,109
1298
+ angr-9.2.110.dist-info/entry_points.txt,sha256=Vjh1C8PMyr5dZFMnik5WkEP01Uwr2T73I3a6N32sgQU,44
1299
+ angr-9.2.110.dist-info/top_level.txt,sha256=dKw0KWTbwLXytFvv15oAAG4sUs3ey47tt6DorJG9-hw,5
1300
+ angr-9.2.110.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.1.1)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-manylinux2014_aarch64
5
5
 
angr/misc/import_hooks.py DELETED
@@ -1,63 +0,0 @@
1
- # pylint:disable=import-outside-toplevel
2
- import os.path
3
- import sys
4
- import importlib.util
5
- from importlib.machinery import ModuleSpec
6
-
7
-
8
- class FastPkgResources:
9
- """
10
- A class that replaces pkg_resources. It only implements resource_filename() and forwards all unimplemented
11
- attributes to the original pkg_resources.
12
- """
13
-
14
- def __getattribute__(self, name):
15
- try:
16
- return object.__getattribute__(self, name)
17
- except AttributeError:
18
- # fallback to the real pkg_resources
19
- remove_fake_pkg_resources()
20
- import pkg_resources
21
-
22
- return getattr(pkg_resources, name)
23
-
24
- @staticmethod
25
- def __spec__():
26
- return ModuleSpec("pkg_resources", None)
27
-
28
- def resource_filename(self, package, resource_name):
29
- r = self._resource_filename(package, resource_name)
30
- if r is None:
31
- # fallback to the real pkg_resources
32
- remove_fake_pkg_resources()
33
- import pkg_resources
34
-
35
- return pkg_resources.resource_filename(package, resource_name)
36
- return r
37
-
38
- @staticmethod
39
- def _resource_filename(package, resource_name):
40
- spec = importlib.util.find_spec(package)
41
- if spec is None:
42
- return None
43
- if not spec.origin:
44
- return None
45
- if os.path.isfile(spec.origin):
46
- # get the directory
47
- base_dir = os.path.dirname(spec.origin)
48
- else:
49
- base_dir = spec.origin
50
- resource_path = os.path.join(base_dir, resource_name)
51
- if os.path.exists(resource_path):
52
- return resource_path
53
- return None
54
-
55
-
56
- def import_fake_pkg_resources(force=False):
57
- if force or "pkg_resources" not in sys.modules:
58
- sys.modules["pkg_resources"] = FastPkgResources()
59
-
60
-
61
- def remove_fake_pkg_resources():
62
- if isinstance(sys.modules.get("pkg_resources", None), FastPkgResources):
63
- sys.modules.pop("pkg_resources")