unicorn icon indicating copy to clipboard operation
unicorn copied to clipboard

Python bindings: DeprecationWarning of pkg_resources when using Unicorn through pytest

Open QDucasse opened this issue 1 year ago • 2 comments

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:

  • The import statement from line 8:
- 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.

  • The usage of pkg_resources from line 85:
_path_list = [os.getenv('LIBUNICORN_PATH', None),
-                     pkg_resources.resource_filename(__name__, 'lib'),
+                    resources.files("unicorn") / 'lib',
                      os.path.join(os.path.split(__file__)[0], 'lib'),
                       '',
                      distutils.sysconfig.get_python_lib(),
                       "/usr/local/lib/" if sys.platform == 'darwin' else '/usr/lib64',
                      os.getenv('PATH', '')]

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?

QDucasse avatar May 03 '23 11:05 QDucasse

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?

wtdcode avatar May 03 '23 17:05 wtdcode

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!

QDucasse avatar May 04 '23 08:05 QDucasse