unicorn-engine / unicorn

Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
http://www.unicorn-engine.org
GNU General Public License v2.0
7.53k stars 1.33k forks source link

Python bindings: DeprecationWarning of pkg_resources when using Unicorn through pytest #1829

Open QDucasse opened 1 year ago

QDucasse commented 1 year ago

Hello, I stumbled upon this issue by using Unicorn in my test framework and wanted to notify: a DeprecationWarning is raised for pkg_resources.resource_filename with the 67.5.0 update of setuptools. I used exclusively unicorn 2.0.1.post1 and tried with setuptools 67.5.0.

To test the behavior, running the following file with pytest test.py raises the warning:

# test.py
from unicorn import Uc

As a solution (I can propose a PR directly but would like to discuss some things), the pkg_resources usage should be replaced by importlib resources. Following the migration guide as well as this legacy API discussion, the following lines would need to be changed from unicorn.py:

- import pkg_resources
+ if sys.version_info < (3, 9):
+    import importlib_resources as resources
+ else:
+    from importlib import resources

Note: importlib_resources is a backport of importlib.resources for older python versions, this fix works for python 3.8 but requires the installation of the backport.

Note: The comment line 78 might need to be changed as well!

However, the raw unicorn in resources.files has to replace the __name__ that was here before that referenced unicorn.unicorn. The exact same issue occurs in the capstone disassembler (which I can open an issue for) and the same fix is possible but since the package discovery occurs in the __init__.py file, it can keep resources.files(__name__) / "lib.

Before proposing a PR, is this solution acceptable (or even needed?) for you?

wtdcode commented 1 year ago

However, the raw unicorn in resources.files has to replace the name that was here before that referenced unicorn.unicorn. The exact same issue occurs in the capstone disassembler (which I can open an issue for) and the same fix is possible but since the package discovery occurs in the init.py file, it can keep resources.files(name) / "lib.

I'm confused by these lines about __name__. How does it relate to your changes?

QDucasse commented 1 year ago

I just wanted to point out the change from __name__ (which resolved to unicorn.unicorn and was fine for pkg_resources, but is not anymore for resources) to unicorn. This change makes it work and not raise a TypeError: 'unicorn.unicorn' is not a package. In capstone, the same issue occurs but since pkg_resources.resource_filename(__name__, 'lib') is used in the __init__.py file, __name__ resolves to capstone directly and not capstone.capstone!