Skip to content

bpo-8525: help() on a type now shows builtin subclasses #5066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 21, 2018

Conversation

CuriousLearner
Copy link
Member

@CuriousLearner CuriousLearner commented Dec 31, 2017

@CuriousLearner
Copy link
Member Author

So, seems like it when this random seed 7657408 is used to run the tests, when they fail the test test_unget_wch.

I'm not sure how do we particularly debug and fix the issue.

@vstinner Can you please help?

@CuriousLearner
Copy link
Member Author

The test passes on running a separate build for the same change on my own fork: https://travis-ci.org/CuriousLearner/cpython/builds/325741101

@vstinner
Copy link
Member

@CuriousLearner: Sorry, I don't understand your comment. What do you expect from me? Your PR changes pydoc, but I tested test_pydoc locally: it pass. So what is your problem?

@CuriousLearner
Copy link
Member Author

@vstinner So, the issue is that the tests passes. But they fail when they run in a particular order; probably right now when randseed is 7657408. Can you guide me how can I debug this behavior?
I ran another travis build on my own fork and it started with another randseed which seems to pass: https://travis-ci.org/CuriousLearner/cpython/builds/325741101

How can I debug this particular behaviour ?

@vstinner
Copy link
Member

vstinner commented Jan 20, 2018 via email

@CuriousLearner
Copy link
Member Author

@vstinner Sorry, if it was not clear. It is the Travis build in this PR that failed.

Here is the failed test:

======================================================================
FAIL: test_semaphore_tracker (test.test_multiprocessing_fork.TestSemaphoreTracker)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/python/cpython/Lib/test/_test_multiprocessing.py", line 4380, in test_semaphore_tracker
    _multiprocessing.sem_unlink(name2)
AssertionError: OSError not raised

And here are the logs: https://travis-ci.org/python/cpython/jobs/323647995#L2592

@vstinner
Copy link
Member

FAIL: test_semaphore_tracker (test.test_multiprocessing_fork.TestSemaphoreTracker)

Oh, this one... It's unrelated to your change. It's a race condition in test_multiprocessing_fork: I guess that the test fails depending on the system load. Sadly, it's something common in the Python test suite, even if we are trying to fix all these race conditions one by one, when one bug becomes too often on our CI :-)

See https://bugs.python.org/issue31687

To reproduce the issue, you should increase the system load to make your system slower and make timeouts more likely, and change the order in which processes are run. I'm using the "stress" utility on Linux for that. But sometimes, the best stress tool... is the Python test suite, since running the full test suite in multiple processes in parallel (./python -m test -j0 -r) runs various workloads, and so sometimes trigger bugs which would be very hard to trigger othewise.

Terminal 1: run "./python -m test -j0 -r", stress or anything else to make the system slower

Terminal 2: run "./python -m test test_multiprocessing_fork -m test_semaphore_tracker -F -v" which runs the test in a loop until it fails.

Lib/pydoc.py Outdated
# List the built-in subclasses, if any:
subclasses = [
cls.__name__ for cls in object.__subclasses__()
if cls.__module__ == 'builtins'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Elsewhere in this file we test against object.__module__ - I think this is relevant for python 2, but consistency seems useful anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nevermind - this is not the builtin object.

@eric-wieser
Copy link
Contributor

What does help(object) now print?

@CuriousLearner
Copy link
Member Author

@eric-wieser The help(object) now returns the following:

Help on class object in module builtins:

class object
 |  The most base type
 |
 |  Built-in subclasses:
 |      BaseException
 |      EncodingMap
 |      NoneType
 |      NotImplementedType
 |      PyCapsule
 |      async_generator
 |      builtin_function_or_method
 |      bytearray
 |      bytearray_iterator
 |      bytes
 |      bytes_iterator
 |      callable_iterator
 |      cell
 |      classmethod
 |      classmethod_descriptor
 |      code
 |      complex
 |      coroutine
 |      coroutine_wrapper
 |      dict
 |      dict_itemiterator
 |      dict_items
 |      dict_keyiterator
 |      dict_keys
 |      dict_valueiterator
 |      dict_values
 |      ellipsis
 |      enumerate
 |      fieldnameiterator
 |      filter
 |      float
 |      formatteriterator
 |      frame
 |      frozenset
 |      function
 |      generator
 |      getset_descriptor
 |      instancemethod
 |      int
 |      iterator
 |      list
 |      list_iterator
 |      list_reverseiterator
 |      longrange_iterator
 |      managedbuffer
 |      map
 |      mappingproxy
 |      member_descriptor
 |      memoryview
 |      method
 |      method-wrapper
 |      method_descriptor
 |      module
 |      moduledef
 |      odict_iterator
 |      property
 |      range
 |      range_iterator
 |      reversed
 |      set
 |      set_iterator
 |      slice
 |      staticmethod
 |      stderrprinter
 |      str
 |      str_iterator
 |      super
 |      traceback
 |      tuple
 |      tuple_iterator
 |      type
 |      weakcallableproxy
 |      weakproxy
 |      weakref
 |      wrapper_descriptor
 |      zip

@eric-wieser
Copy link
Contributor

That strikes me as thoroughly unhelpful - perhaps it should not print anything for object?

@CuriousLearner
Copy link
Member Author

@eric-wieser Sure. Sounds good to me. I've made some modifications so that we don't push the sub-classes details for object

Lib/pydoc.py Outdated
cls.__name__ for cls in object.__subclasses__()
if cls.__module__ == 'builtins'
]
if subclasses and object.__class__ != type:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you didn't want object is not builtins.object? What you have now only shows subclasses for objects with a metaclass.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yes. You're correct! I've updated the patch to reflect the changes.

@CuriousLearner
Copy link
Member Author

@ncoghlan @vstinner Can you please take a look here?

@ncoghlan
Copy link
Contributor

See my comments at https://bugs.python.org/issue8525#msg321651

If we do make this change, it's going to need a hard upper limit on the number of subclasses shown, even within the exception hierarchy.

* master: (1159 commits)
  bpo-34087: Fix buffer overflow in int(s) and similar functions (pythonGH-8274)
  bpo-34108: Fix double carriage return in 2to3 on Windows (python#8271)
  bpo-4260: Document that ctypes.xFUNCTYPE are decorators (pythonGH-7924)
  bpo-33723: Fix test_time.test_thread_time() (pythonGH-8267)
  bpo-33967: Remove use of deprecated assertRaisesRegexp() (pythonGH-8261)
  bpo-34080: Fix a memory leak in the compiler. (pythonGH-8222)
  Enable GUI testing on Travis Linux builds via Xvfb (pythonGH-7887)
  bpo-23927: Make getargs.c skipitem() skipping 'w*'. (pythonGH-8192)
  bpo-33648: Remove PY_WARN_ON_C_LOCALE (pythonGH-7114)
  bpo-34092, test_logging: increase SMTPHandlerTest timeout (pythonGH-8245)
  Simplify __all__ in multiprocessing (pythonGH-6856)
  bpo-34083: Update dict order in Functional HOWTO (pythonGH-8230)
  Doc: Point to Simple statements section instead of PEP (pythonGH-8238)
  bpo-29442: Replace optparse with argparse in setup.py (pythonGH-139)
  bpo-33597: Add What's New for PyGC_Head (pythonGH-8236)
  Dataclasses: Fix example on 30.6.8, add method should receive a list rather than an integer. (pythonGH-8038)
  Fix documentation for input and output tutorial (pythonGH-8231)
  bpo-34009: Expand on platform support changes (pythonGH-8022)
  Factor-out two substantially identical code blocks. (pythonGH-8219)
  bpo-34031: fix incorrect usage of self.fail in two tests (pythonGH-8091)
  ...
@CuriousLearner
Copy link
Member Author

@ncoghlan I've made the changes to display at most 4 subclasses.

But IMHO, there should be also a way to see all the subclasses if I want to see. That could be a pretty useful feature for folks. What do you think?

@CuriousLearner
Copy link
Member Author

@ncoghlan I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

: please review the changes made to this pull request.

@CuriousLearner
Copy link
Member Author

@ncoghlan I'm not sure how the no. of subclasses changes on my local and the CI. That is why the tests seem to fail on CI.

I'm curious to know on what's the reasoning behind this.

Lib/pydoc.py Outdated
@@ -1254,6 +1254,24 @@ def makename(c, m=object.__module__):
push(' ' + makename(base))
push('')

# List the built-in subclasses, if any:
subclasses = sorted(
(str(cls.__name__) for cls in object.__subclasses__() \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backslash not needed here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, nice catch! Fixed this :)

Thank you!

@willingc willingc self-requested a review October 7, 2018 09:24
@CuriousLearner
Copy link
Member Author

Hey @ncoghlan @vstinner

I think this patch was really close (and it has been 3 months since the last update :) ), I would really appreciate your help if you can guide me about how the number of subclasses is varying on locally and on CI so that I can fix these up :)

Are these OS dependent?

* master: (621 commits)
  Update opcode.h header comment to mention the source data file (pythonGH-9935)
  bpo-34936: Fix TclError in tkinter.Spinbox.selection_element(). (pythonGH-9760)
  Updated documentation on logging.debug(). (pythonGH-9946)
  bpo-34765: Update the install-sh file (pythonGH-9592)
  bpo-35008: Fix possible leaks in Element.__setstate__(). (pythonGH-9924)
  bpo-35011: Restore use of pyexpatns.h in libexpat (pythonGH-9939)
  bpo-24658: Fix read/write greater than 2 GiB on macOS (pythonGH-1705)
  Add missing comma to wsgiref doc (pythonGH-9932)
  bpo-23420: Verify the value of '-s' when execute the CLI of cProfile (pythonGH-9925)
  Doc: Fix is_prime (pythonGH-9909)
  In email docs, correct spelling of foregoing (python#9856)
  In email.parser in message_from_bytes, update `strict` to `policy` (python#9854)
  bpo-34997: Fix test_logging.ConfigDictTest.test_out_of_order (pythonGH-9913)
  Added CLI starter example to logging cookbook. (pythonGH-9910)
  bpo-34783: Fix test_nonexisting_script() (pythonGH-9896)
  bpo-23554: Change echo server example class name from EchoServerClientProtocol to EchoServerProtocol (pythonGH-9859)
  bpo-34989: python-gdb.py: fix current_line_num() (pythonGH-9889)
  Stop using deprecated logging API in Sphinx suspicious checker (pythonGH-9875)
  fix dangling keyfunc examples in documentation of heapq and sorted (python#1432)
  bpo-34844: logging.Formatter enhancement - Ensure style and format string matches in logging.Formatter  (pythonGH-9703)
  ...
@CuriousLearner
Copy link
Member Author

Hi, @ncoghlan @vstinner I've fixed up everything. CI is all good now.

Can you please take a look?

Copy link
Contributor

@willingc willingc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for persisting @CuriousLearner.

Copy link
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally, I think this version is OK (and counts as an improvement over the status quo, even if further changes end up being made).

Hardcoding an exact number of subclasses into the test case is going to be annoying to maintain though (e.g. it already needs to be skipped Windows), so I think relaxing that check to just require it to be a number (\d+ in a regex) is fine.

" | BaseException\n"
" | builtin_function_or_method\n"
" | bytearray\n"
" | ... and 86 other subclasses")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the number here is going to make the test overly fragile, so I'd suggest making this a regex and using assertRegexMatches instead of assertIn.

@@ -517,6 +517,38 @@ def test_stripid(self):
self.assertEqual(stripid("<type 'exceptions.Exception'>"),
"<type 'exceptions.Exception'>")

@unittest.skipIf(sys.platform == 'win32', "Different no of subclasses on win")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the regex change below, it won't be necessary to skip this test on Windows any more.

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

Copy link
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and made the assertIn -> assertRegex change, so assuming that passes CI, I think this will be good to go.

@ncoghlan ncoghlan changed the title bpo-8525: help() now shows exceptions' builtin subclasses bpo-8525: help() on a type now shows builtin subclasses Oct 21, 2018
@ncoghlan
Copy link
Contributor

Also tweaked NEWS entry wording and PR title after GH prompted me to edit the commit message on the squash commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants