mdmintz / pynose

pynose fixes nose to extend unittest and make testing easier
https://pypi.org/project/pynose/
GNU Lesser General Public License v2.1
11 stars 6 forks source link

inspect.getargspec no longer available on Python 3.11 #4

Closed adiroiban closed 1 year ago

adiroiban commented 1 year ago

Hi Michael

Thanks for setting up this fork.

I am trying to use this project, in an effort to stop using my personal fork of nose.

I can't get this to work with Python 3.11

I see that the GitHub Action job run with 3.11 is green - https://github.com/mdmintz/pynose/actions/runs/4867487327/jobs/8680119707

I guess that the automated tests don't do any package discovery

The error is

AttributeError: module 'inspect' has no attribute 'getargspec'`

$ ./build-py3/bin/pynose src/chevah_compat/tests/
E
======================================================================
ERROR: test suite for <module 'chevah_compat.tests' from '/home/adi/chevah/compat/src/chevah_compat/tests/__init__.py'>
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/adi/chevah/compat/build-py3/lib/python3.11/site-packages/nose/suite.py", line 172, in run
    self.setUp()
  File "/home/adi/chevah/compat/build-py3/lib/python3.11/site-packages/nose/suite.py", line 247, in setUp
    self.setupContext(ancestor)
  File "/home/adi/chevah/compat/build-py3/lib/python3.11/site-packages/nose/suite.py", line 268, in setupContext
    try_run(context, names)
  File "/home/adi/chevah/compat/build-py3/lib/python3.11/site-packages/nose/util.py", line 416, in try_run
    args, varargs, varkw, defaults = inspect.getargspec(func)
                                     ^^^^^^^^^^^^^^^^^^
AttributeError: module 'inspect' has no attribute 'getargspec'

----------------------------------------------------------------------
Ran 0 tests in 0.001s

FAILED (errors=1)

I have something like this.

$ ./build-py3/bin/nosetests --version
nosetests version 1.4.4

$ ./build-py3/bin/pynose --version
pynose version 1.4.4

$ ./build-py3/bin/python --version
Python 3.11.3

$ cat build-py3/bin/pynose 
#!/home/adi/chevah/compat/build-py3/bin/python

from nose import main

if __name__ == '__main__':
    main()

$ cat /home/adi/chevah/compat/build-py3/lib/python3.11/site-packages/nose/__init__.py 
import sys
from nose.core import collector, main, run, run_exit, runmodule
from nose.exc import SkipTest, DeprecatedTest
from nose.tools import with_setup
from nose.__version__ import __version__
import collections

__author__ = 'Jason Pellerin (Original) / Michael Mintz (Update)'
version_list = [int(i) for i in __version__.split(".") if i.isdigit()]
__versioninfo__ = tuple(version_list)
__version__ = '.'.join(map(str, __versioninfo__))
__all__ = [
    'main', 'run', 'run_exit', 'runmodule', 'with_setup',
    'SkipTest', 'DeprecatedTest', 'collector'
]
if sys.version_info >= (3, 10):
    collections.Callable = collections.abc.Callable
mdmintz commented 1 year ago

@adiroiban Thanks for reporting this. I found a workaround: https://github.com/pyinvoke/invoke/issues/833#issuecomment-1293148106

I'll be shipping a new release with the fix very soon.

adiroiban commented 1 year ago

This is the way I am patching it for nose

inspect.getargspec = lambda func: inspect.getfullargspec(func)[:4]
mdmintz commented 1 year ago

@adiroiban If you use:

if not hasattr(inspect, 'getargspec'):
    inspect.getargspec = inspect.getfullargspec

does that work for you? That seems to be the solution that many people liked.

adiroiban commented 1 year ago

As far as I remember, no. It doesn't work.

See the docs https://docs.python.org/3/library/inspect.html#inspect.getfullargspec

getfullargspec returns FullArgSpec(args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations)

nose usage is args, varargs, varkw, defaults = inspect.getargspec(func)

but nose is only using the args from the return value.


Wouldn't it be better to have everything in the pynose namespace ?

That is, instead of patching the vanilla nose, why not continue the development as a separate project?

mdmintz commented 1 year ago

@adiroiban I'll start with the quick patches, and then make more changes as needed.

I'll use the following after importing inspect:

inspect.getargspec = lambda func: inspect.getfullargspec(func)[:4]

If you say that solves your current issue, I can make the necessary changes quickly and push a release within an hour.

adiroiban commented 1 year ago

I don't think that we need to rush. I already have this working on my fork ... and for practical and security reasons I will always use a fork from a private PyPI server :)

I think is best to update the automated tests to reveal this issue and then push a fix.

Let me give this a try. I will push a PR and I will give you access to the branch.

mdmintz commented 1 year ago

@adiroiban If the only change is:

if not hasattr(inspect, "getargspec"):
    inspect.getargspec = lambda func: inspect.getfullargspec(func)[:4]

I can push that change quickly.

adiroiban commented 1 year ago

I am not sure that is the only change.

But most probably it is.

It would have been nice to have the full nose test available and run those tests, rather than reinventing tests for pynose

Let's check the changes in the PR.

I first would like to see the CI failing and then fix the issue :)

And also add a NEWS.md or some release notes file to keep track of latest changes in the repo :p

mdmintz commented 1 year ago

Resolved in 1.4.5 - https://github.com/mdmintz/pynose/releases/tag/v1.4.5