ljcooke / see

Python's dir() for humans.
https://ljcooke.github.io/see/
BSD 3-Clause "New" or "Revised" License
245 stars 18 forks source link

Error in JupyterLite #17

Open spring-haru opened 1 year ago

spring-haru commented 1 year ago

Description

An error occurs in using see in JupyterLite

Steps to reproduce

  1. Prepare JupyterLite with see included in requirements.txt
  2. from see import see
  3. see(<an object>) generates an error

Expected behaviour: [...]

No error

Actual behaviour: [...]

The following error message is displayed

Version info

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File /lib/python3.10/site-packages/IPython/core/formatters.py:707, in PlainTextFormatter.__call__(self, obj)
    700 stream = StringIO()
    701 printer = pretty.RepresentationPrinter(stream, self.verbose,
    702     self.max_width, self.newline,
    703     max_seq_length=self.max_seq_length,
    704     singleton_pprinters=self.singleton_printers,
    705     type_pprinters=self.type_printers,
    706     deferred_pprinters=self.deferred_printers)
--> 707 printer.pretty(obj)
    708 printer.flush()
    709 return stream.getvalue()

File /lib/python3.10/site-packages/IPython/lib/pretty.py:410, in RepresentationPrinter.pretty(self, obj)
    407                         return meth(obj, self, cycle)
    408                 if cls is not object \
    409                         and callable(cls.__dict__.get('__repr__')):
--> 410                     return _repr_pprint(obj, self, cycle)
    412     return _default_pprint(obj, self, cycle)
    413 finally:

File /lib/python3.10/site-packages/IPython/lib/pretty.py:778, in _repr_pprint(obj, p, cycle)
    776 """A pprint that just redirects to the normal repr function."""
    777 # Find newlines and replace them with p.break_()
--> 778 output = repr(obj)
    779 lines = output.splitlines()
    780 with p.group():

File /lib/python3.10/site-packages/see/output.py:46, in SeeResult.__repr__(self)
     43 else:
     44     indent = ' ' * MAX_INDENT
---> 46 return textwrap.fill(''.join(padded), term.line_width(),
     47                      initial_indent=indent,
     48                      subsequent_indent=indent)

File /lib/python3.10/site-packages/see/term.py:57, in line_width(default_width, max_width)
     52 def line_width(default_width=DEFAULT_LINE_WIDTH, max_width=MAX_LINE_WIDTH):
     53     """
     54     Return the ideal column width for the output from :func:`see.see`, taking
     55     the terminal width into account to avoid wrapping.
     56     """
---> 57     width = term_width()
     58     if width:  # pragma: no cover (no terminal info in Travis CI)
     59         return min(width, max_width)

File /lib/python3.10/site-packages/see/term.py:34, in term_width()
     32 if fcntl and termios:
     33     try:
---> 34         winsize = fcntl.ioctl(0, termios.TIOCGWINSZ, '    ')
     35         _, width = struct.unpack('hh', winsize)
     36         return width

AttributeError: module 'fcntl' has no attribute 'ioctl'
ljcooke commented 1 year ago

Thanks for reporting this!

It seems to be a problem with JupyterLite's standard library. It provides a module named fnctl but the module is empty.

I'm out of practice with Python but I'll try releasing a patch some day. In the meantime, here's a hack that seems to get it working in JupyterLite.

Instead of from see import see, try running this:

import see
see.term.term_width = lambda: None
see = see.see
spring-haru commented 1 year ago

The snippet worked. Thanks!