Hello community, here is the log from the commit of package python-urwid for openSUSE:Factory checked in at 2020-10-29 09:45:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-urwid (Old) and /work/SRC/openSUSE:Factory/.python-urwid.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-urwid" Thu Oct 29 09:45:20 2020 rev:16 rq:835016 version:2.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-urwid/python-urwid.changes 2020-02-09 20:48:36.162881368 +0100 +++ /work/SRC/openSUSE:Factory/.python-urwid.new.3463/python-urwid.changes 2020-10-29 09:45:27.744007443 +0100 @@ -1,0 +2,23 @@ +Wed Sep 16 21:28:40 UTC 2020 - Dirk Mueller <dmuel...@suse.com> + +- udpate to 2.1.1: + * Add TrioEventLoop.run_async(), removed nursery constructor arg (#392) (by + Tamás Nepusz) + * Add wrap_around kwarg to SimpleListWalkers (by Krzysztof Królczyk) + * Change documentation on Terminal (by James Johnson) + * Remove debug documentation change test (by James Johnson) + * Remove support for py34 (by Andrey Semakin) + * Remove invalid escape sequence (by Andrey Lebedev) + * Fix GridFlow keypress handling when v_sep is 0 (by Aurelien Grenotton) + * Fix Terminal in ListBox (#382) (by James Johnson) + * Fix Crash on `fg`, SIGCONT (after Ctrl-Z, SIGSTOP, SIGTSTP) (by goncalopp) + * Fix 256-color mode on some terminals. Addresses #404. (by Tony Cebzanov) + * vterm: reduce __init__ boilerplate (by max ulidtko) + * vterm: errno 5 is not EOF. (by max ulidtko) + * Terminal: use UTF-8 by default. (by max ulidtko) + * Instance of Terminal has no __super attr -- thanks pylint! (by max ulidtko) + * Do not call wait_readable with a closed fd in TrioEventLoop (by Michael + Hudson-Doyle) + * Make options a static method where applicable (by Philip Matura) + +------------------------------------------------------------------- Old: ---- urwid-2.1.0.tar.gz New: ---- urwid-2.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-urwid.spec ++++++ --- /var/tmp/diff_new_pack.u5Or9h/_old 2020-10-29 09:45:28.508008164 +0100 +++ /var/tmp/diff_new_pack.u5Or9h/_new 2020-10-29 09:45:28.512008168 +0100 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-urwid -Version: 2.1.0 +Version: 2.1.1 Release: 0 Summary: A full-featured console (xterm et al.) user interface library License: LGPL-2.1-or-later ++++++ urwid-2.1.0.tar.gz -> urwid-2.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/PKG-INFO new/urwid-2.1.1/PKG-INFO --- old/urwid-2.1.0/PKG-INFO 2019-11-14 18:02:20.506315500 +0100 +++ new/urwid-2.1.1/PKG-INFO 2020-07-27 01:36:42.933347000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: urwid -Version: 2.1.0 +Version: 2.1.1 Summary: A full-featured console (xterm et al.) user interface library Home-page: http://urwid.org/ Author: Ian Ward @@ -22,7 +22,7 @@ - Display modules include raw, curses, and experimental LCD and web displays - Support for UTF-8, simple 8-bit and CJK encodings - 24-bit (true color), 256 color, and 88 color mode support - - Compatible with Python 2.7, 3.4+ and PyPy + - Compatible with Python 2.7, 3.5+ and PyPy Home Page: http://urwid.org/ @@ -61,7 +61,6 @@ ========================= - 2.7 - - 3.4 - 3.5 - 3.6 - 3.7 @@ -83,68 +82,126 @@ `tonycpsu <//github.com/tonycpsu>`_, `ulidtko <//github.com/ulidtko>`_ - Contributors - ------------ + Authors + ------- - `aathan <//github.com/aathan>`_, `abadger <//github.com/abadger>`_, `aglyzov <//github.com/aglyzov>`_, + `agrenott <//github.com/agrenott>`_, `akosthekiss <//github.com/akosthekiss>`_, `alexozer <//github.com/alexozer>`_, + `alobbs <//github.com/alobbs>`_, + `and-semakin <//github.com/and-semakin>`_, `andersk <//github.com/andersk>`_, + `andrewshadura <//github.com/andrewshadura>`_, `aszlig <//github.com/aszlig>`_, - `atsampson <//github.com/atsampson>`_, `BkPHcgQL3V <//github.com/BkPHcgQL3V>`_, - `BlindB0 <//github.com/BlindB0>`_, - `bukzor <//github.com/bukzor>`_, + `carlos-jenkins <//github.com/carlos-jenkins>`_, + `d0c-s4vage <//github.com/d0c-s4vage>`_, + `dnaeon <//github.com/dnaeon>`_, + `drestebon <//github.com/drestebon>`_, + `EdwardBetts <//github.com/EdwardBetts>`_, `eevee <//github.com/eevee>`_, + `elenril <//github.com/elenril>`_, + `extempore <//github.com/extempore>`_, + `fabiand <//github.com/fabiand>`_, `federicotdn <//github.com/federicotdn>`_, + `floppym <//github.com/floppym>`_, `garrison <//github.com/garrison>`_, `geier <//github.com/geier>`_, - `grugq <//github.com/grugq>`_, - `hkoof <//github.com/hkoof>`_, + `grzaks <//github.com/grzaks>`_, `hootnot <//github.com/hootnot>`_, `horazont <//github.com/horazont>`_, + `ids1024 <//github.com/ids1024>`_, `inducer <//github.com/inducer>`_, `ismail-s <//github.com/ismail-s>`_, - `italomaia-bk <//github.com/italomaia-bk>`_, `ivanov <//github.com/ivanov>`_, + `jeblair <//github.com/jeblair>`_, `Julian <//github.com/Julian>`_, `jwilk <//github.com/jwilk>`_, - `kajojify <//github.com/kajojify>`_, - `Kamik423 <//github.com/Kamik423>`_, + `kedder <//github.com/kedder>`_, + `KennethNielsen <//github.com/KennethNielsen>`_, `kkrolczyk <//github.com/kkrolczyk>`_, - `marienz <//github.com/marienz>`_, + `larsks <//github.com/larsks>`_, + `Lothiraldan <//github.com/Lothiraldan>`_, `matthijskooijman <//github.com/matthijskooijman>`_, + `mattymo <//github.com/mattymo>`_, `mbarkhau <//github.com/mbarkhau>`_, - `mgiusti <//github.com/mgiusti>`_, - `mikemccracken <//github.com/mikemccracken>`_, + `mgk <//github.com/mgk>`_, + `mimi1vx <//github.com/mimi1vx>`_, + `mobyte0 <//github.com/mobyte0>`_, + `mwhudson <//github.com/mwhudson>`_, + `nchavez324 <//github.com/nchavez324>`_, + `neumond <//github.com/neumond>`_, `nocarryr <//github.com/nocarryr>`_, `ntamas <//github.com/ntamas>`_, `olleolleolle <//github.com/olleolleolle>`_, `pazz <//github.com/pazz>`_, `pniedzwiedzinski <//github.com/pniedzwiedzinski>`_, `raek <//github.com/raek>`_, - `richrd <//github.com/richrd>`_, + `renegarcia <//github.com/renegarcia>`_, + `rianhunter <//github.com/rianhunter>`_, `rndusr <//github.com/rndusr>`_, - `robla <//github.com/robla>`_, `rr- <//github.com/rr->`_, - `seleem1337 <//github.com/seleem1337>`_, - `SenchoPens <//github.com/SenchoPens>`_, - `shyal <//github.com/shyal>`_, - `sitaktif <//github.com/sitaktif>`_, + `rwarren <//github.com/rwarren>`_, + `seanhussey <//github.com/seanhussey>`_, + `Sjc1000 <//github.com/Sjc1000>`_, + `ssbr <//github.com/ssbr>`_, `tdryer <//github.com/tdryer>`_, `techtonik <//github.com/techtonik>`_, + `tompickering <//github.com/tompickering>`_, `tu500 <//github.com/tu500>`_, + `uSpike <//github.com/uSpike>`_, `usrlocalben <//github.com/usrlocalben>`_, - `wackywendell <//github.com/wackywendell>`_, + `waveform80 <//github.com/waveform80>`_, `wernight <//github.com/wernight>`_, + `Wesmania <//github.com/Wesmania>`_, `westurner <//github.com/westurner>`_, - `whospal <//github.com/whospal>`_, - `Wilfred <//github.com/Wilfred>`_, `winbornejw <//github.com/winbornejw>`_, + `xndcn <//github.com/xndcn>`_, `xnox <//github.com/xnox>`_, - `yanzixiang <//github.com/yanzixiang>`_ + `zrax <//github.com/zrax>`_ + + Contributors + ------------ + + `aleufroy <//github.com/aleufroy>`_, + `andy-z <//github.com/andy-z>`_, + `anttin2020 <//github.com/anttin2020>`_, + `belak <//github.com/belak>`_, + `berney <//github.com/berney>`_, + `bk2204 <//github.com/bk2204>`_, + `bukzor <//github.com/bukzor>`_, + `Chipsterjulien <//github.com/Chipsterjulien>`_, + `chrisspen <//github.com/chrisspen>`_, + `dimays <//github.com/dimays>`_, + `dlo <//github.com/dlo>`_, + `douglas-larocca <//github.com/douglas-larocca>`_, + `goncalopp <//github.com/goncalopp>`_, + `Gordin <//github.com/Gordin>`_, + `grugq <//github.com/grugq>`_, + `hkoof <//github.com/hkoof>`_, + `Hoolean <//github.com/Hoolean>`_, + `hukka <//github.com/hukka>`_, + `itaisod <//github.com/itaisod>`_, + `ixxra <//github.com/ixxra>`_, + `Kelketek <//github.com/Kelketek>`_, + `livibetter <//github.com/livibetter>`_, + `marlox-ouda <//github.com/marlox-ouda>`_, + `MonAaraj <//github.com/MonAaraj>`_, + `mountainstorm <//github.com/mountainstorm>`_, + `mselee <//github.com/mselee>`_, + `nyov <//github.com/nyov>`_, + `pquentin <//github.com/pquentin>`_, + `RRMoelker <//github.com/RRMoelker>`_, + `shadedKE <//github.com/shadedKE>`_, + `sitaktif <//github.com/sitaktif>`_, + `sporkexec <//github.com/sporkexec>`_, + `thehunmonkgroup <//github.com/thehunmonkgroup>`_, + `thisch <//github.com/thisch>`_, + `TomasTomecek <//github.com/TomasTomecek>`_, + `ttanner <//github.com/ttanner>`_, + `vega0 <//github.com/vega0>`_ .. |pypi| image:: http://img.shields.io/pypi/v/urwid.svg @@ -178,7 +235,6 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/README.rst new/urwid-2.1.1/README.rst --- old/urwid-2.1.0/README.rst 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/README.rst 2020-07-27 01:36:41.000000000 +0200 @@ -19,7 +19,7 @@ - Display modules include raw, curses, and experimental LCD and web displays - Support for UTF-8, simple 8-bit and CJK encodings - 24-bit (true color), 256 color, and 88 color mode support -- Compatible with Python 2.7, 3.4+ and PyPy +- Compatible with Python 2.7, 3.5+ and PyPy Home Page: http://urwid.org/ @@ -58,7 +58,6 @@ ========================= - 2.7 -- 3.4 - 3.5 - 3.6 - 3.7 @@ -80,68 +79,126 @@ `tonycpsu <//github.com/tonycpsu>`_, `ulidtko <//github.com/ulidtko>`_ -Contributors ------------- +Authors +------- -`aathan <//github.com/aathan>`_, `abadger <//github.com/abadger>`_, `aglyzov <//github.com/aglyzov>`_, +`agrenott <//github.com/agrenott>`_, `akosthekiss <//github.com/akosthekiss>`_, `alexozer <//github.com/alexozer>`_, +`alobbs <//github.com/alobbs>`_, +`and-semakin <//github.com/and-semakin>`_, `andersk <//github.com/andersk>`_, +`andrewshadura <//github.com/andrewshadura>`_, `aszlig <//github.com/aszlig>`_, -`atsampson <//github.com/atsampson>`_, `BkPHcgQL3V <//github.com/BkPHcgQL3V>`_, -`BlindB0 <//github.com/BlindB0>`_, -`bukzor <//github.com/bukzor>`_, +`carlos-jenkins <//github.com/carlos-jenkins>`_, +`d0c-s4vage <//github.com/d0c-s4vage>`_, +`dnaeon <//github.com/dnaeon>`_, +`drestebon <//github.com/drestebon>`_, +`EdwardBetts <//github.com/EdwardBetts>`_, `eevee <//github.com/eevee>`_, +`elenril <//github.com/elenril>`_, +`extempore <//github.com/extempore>`_, +`fabiand <//github.com/fabiand>`_, `federicotdn <//github.com/federicotdn>`_, +`floppym <//github.com/floppym>`_, `garrison <//github.com/garrison>`_, `geier <//github.com/geier>`_, -`grugq <//github.com/grugq>`_, -`hkoof <//github.com/hkoof>`_, +`grzaks <//github.com/grzaks>`_, `hootnot <//github.com/hootnot>`_, `horazont <//github.com/horazont>`_, +`ids1024 <//github.com/ids1024>`_, `inducer <//github.com/inducer>`_, `ismail-s <//github.com/ismail-s>`_, -`italomaia-bk <//github.com/italomaia-bk>`_, `ivanov <//github.com/ivanov>`_, +`jeblair <//github.com/jeblair>`_, `Julian <//github.com/Julian>`_, `jwilk <//github.com/jwilk>`_, -`kajojify <//github.com/kajojify>`_, -`Kamik423 <//github.com/Kamik423>`_, +`kedder <//github.com/kedder>`_, +`KennethNielsen <//github.com/KennethNielsen>`_, `kkrolczyk <//github.com/kkrolczyk>`_, -`marienz <//github.com/marienz>`_, +`larsks <//github.com/larsks>`_, +`Lothiraldan <//github.com/Lothiraldan>`_, `matthijskooijman <//github.com/matthijskooijman>`_, +`mattymo <//github.com/mattymo>`_, `mbarkhau <//github.com/mbarkhau>`_, -`mgiusti <//github.com/mgiusti>`_, -`mikemccracken <//github.com/mikemccracken>`_, +`mgk <//github.com/mgk>`_, +`mimi1vx <//github.com/mimi1vx>`_, +`mobyte0 <//github.com/mobyte0>`_, +`mwhudson <//github.com/mwhudson>`_, +`nchavez324 <//github.com/nchavez324>`_, +`neumond <//github.com/neumond>`_, `nocarryr <//github.com/nocarryr>`_, `ntamas <//github.com/ntamas>`_, `olleolleolle <//github.com/olleolleolle>`_, `pazz <//github.com/pazz>`_, `pniedzwiedzinski <//github.com/pniedzwiedzinski>`_, `raek <//github.com/raek>`_, -`richrd <//github.com/richrd>`_, +`renegarcia <//github.com/renegarcia>`_, +`rianhunter <//github.com/rianhunter>`_, `rndusr <//github.com/rndusr>`_, -`robla <//github.com/robla>`_, `rr- <//github.com/rr->`_, -`seleem1337 <//github.com/seleem1337>`_, -`SenchoPens <//github.com/SenchoPens>`_, -`shyal <//github.com/shyal>`_, -`sitaktif <//github.com/sitaktif>`_, +`rwarren <//github.com/rwarren>`_, +`seanhussey <//github.com/seanhussey>`_, +`Sjc1000 <//github.com/Sjc1000>`_, +`ssbr <//github.com/ssbr>`_, `tdryer <//github.com/tdryer>`_, `techtonik <//github.com/techtonik>`_, +`tompickering <//github.com/tompickering>`_, `tu500 <//github.com/tu500>`_, +`uSpike <//github.com/uSpike>`_, `usrlocalben <//github.com/usrlocalben>`_, -`wackywendell <//github.com/wackywendell>`_, +`waveform80 <//github.com/waveform80>`_, `wernight <//github.com/wernight>`_, +`Wesmania <//github.com/Wesmania>`_, `westurner <//github.com/westurner>`_, -`whospal <//github.com/whospal>`_, -`Wilfred <//github.com/Wilfred>`_, `winbornejw <//github.com/winbornejw>`_, +`xndcn <//github.com/xndcn>`_, `xnox <//github.com/xnox>`_, -`yanzixiang <//github.com/yanzixiang>`_ +`zrax <//github.com/zrax>`_ + +Contributors +------------ + +`aleufroy <//github.com/aleufroy>`_, +`andy-z <//github.com/andy-z>`_, +`anttin2020 <//github.com/anttin2020>`_, +`belak <//github.com/belak>`_, +`berney <//github.com/berney>`_, +`bk2204 <//github.com/bk2204>`_, +`bukzor <//github.com/bukzor>`_, +`Chipsterjulien <//github.com/Chipsterjulien>`_, +`chrisspen <//github.com/chrisspen>`_, +`dimays <//github.com/dimays>`_, +`dlo <//github.com/dlo>`_, +`douglas-larocca <//github.com/douglas-larocca>`_, +`goncalopp <//github.com/goncalopp>`_, +`Gordin <//github.com/Gordin>`_, +`grugq <//github.com/grugq>`_, +`hkoof <//github.com/hkoof>`_, +`Hoolean <//github.com/Hoolean>`_, +`hukka <//github.com/hukka>`_, +`itaisod <//github.com/itaisod>`_, +`ixxra <//github.com/ixxra>`_, +`Kelketek <//github.com/Kelketek>`_, +`livibetter <//github.com/livibetter>`_, +`marlox-ouda <//github.com/marlox-ouda>`_, +`MonAaraj <//github.com/MonAaraj>`_, +`mountainstorm <//github.com/mountainstorm>`_, +`mselee <//github.com/mselee>`_, +`nyov <//github.com/nyov>`_, +`pquentin <//github.com/pquentin>`_, +`RRMoelker <//github.com/RRMoelker>`_, +`shadedKE <//github.com/shadedKE>`_, +`sitaktif <//github.com/sitaktif>`_, +`sporkexec <//github.com/sporkexec>`_, +`thehunmonkgroup <//github.com/thehunmonkgroup>`_, +`thisch <//github.com/thisch>`_, +`TomasTomecek <//github.com/TomasTomecek>`_, +`ttanner <//github.com/ttanner>`_, +`vega0 <//github.com/vega0>`_ .. |pypi| image:: http://img.shields.io/pypi/v/urwid.svg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/docs/changelog.rst new/urwid-2.1.1/docs/changelog.rst --- old/urwid-2.1.0/docs/changelog.rst 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/docs/changelog.rst 2020-07-27 01:36:41.000000000 +0200 @@ -2,6 +2,52 @@ Changelog --------- +Urwid 2.1.1 +=========== + +2020-07-26 + + * Add TrioEventLoop.run_async(), removed nursery constructor arg (#392) (by + Tamás Nepusz) + + * Add py38 to Travis tests (by Andrey Semakin) + + * Add popular IDEs folders to .gitignore (by Andrey Semakin) + + * Add wrap_around kwarg to SimpleListWalkers (by Krzysztof Królczyk) + + * Change documentation on Terminal (by James Johnson) + + * Remove debug documentation change test (by James Johnson) + + * Remove support for py34 (by Andrey Semakin) + + * Remove invalid escape sequence (by Andrey Lebedev) + + * Fix GridFlow keypress handling when v_sep is 0 (by Aurelien Grenotton) + + * Fix Terminal in ListBox (#382) (by James Johnson) + + * Fix Crash on `fg`, SIGCONT (after Ctrl-Z, SIGSTOP, SIGTSTP) (by goncalopp) + + * Fix 256-color mode on some terminals. Addresses #404. (by Tony Cebzanov) + + * vterm: reduce __init__ boilerplate (by max ulidtko) + + * vterm: errno 5 is not EOF. (by max ulidtko) + + * Terminal: use UTF-8 by default. (by max ulidtko) + + * Instance of Terminal has no __super attr -- thanks pylint! (by max ulidtko) + + * Do not call wait_readable with a closed fd in TrioEventLoop (by Michael + Hudson-Doyle) + + * Make options a static method where applicable (by Philip Matura) + + * Set up Travis to run py38, speed up build (by Andrey Semakin) + + Urwid 2.1.0 =========== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/docs/tools/templates/indexcontent.html new/urwid-2.1.1/docs/tools/templates/indexcontent.html --- old/urwid-2.1.0/docs/tools/templates/indexcontent.html 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/docs/tools/templates/indexcontent.html 2020-07-27 01:36:41.000000000 +0200 @@ -37,7 +37,7 @@ <div class="section" id="requirements"> <h3>Requirements</h3> <ul> -<li>Python 2.7, 3.4+ or PyPy</li> +<li>Python 2.7, 3.5+ or PyPy</li> <li>Linux, OSX, Cygwin or other unix-like OS</li> <li>python-gi for GlibEventLoop (optional)</li> <li>Twisted for TwistedEventLoop (optional)</li> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/setup.py new/urwid-2.1.1/setup.py --- old/urwid-2.1.0/setup.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/setup.py 2020-07-27 01:36:41.000000000 +0200 @@ -65,7 +65,6 @@ "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/_async_kw_event_loop.py new/urwid-2.1.1/urwid/_async_kw_event_loop.py --- old/urwid-2.1.0/urwid/_async_kw_event_loop.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/_async_kw_event_loop.py 2020-07-27 01:36:41.000000000 +0200 @@ -30,15 +30,8 @@ ``trio`` is an async library for Python 3.5 and later. """ - def __init__(self, nursery=None): - """Constructor. - - Parameters: - nursery: the Trio nursery in which the asynchronous tasks will - execute. `None` will make the event loop use `trio.run()` when - the loop is started and force it to create a nursery on its - own. - """ + def __init__(self): + """Constructor.""" import trio self._idle_handle = 0 @@ -123,13 +116,37 @@ idle_callbacks = self._idle_callbacks - def _exception_handler(exc): - idle_callbacks.clear() - if isinstance(exc, ExitMainLoop): - return None - else: - return exc + # This class is duplicated in run_async(). It would be nice to move + # this somewhere outside, but we cannot do it yet becase we need to + # derive it from self._trio.abc.Instrument + class TrioIdleCallbackInstrument(self._trio.abc.Instrument): + def before_io_wait(self, timeout): + if timeout > 0: + for idle_callback in idle_callbacks.values(): + idle_callback() + + emulate_idle_callbacks = TrioIdleCallbackInstrument() + + with self._trio.MultiError.catch(self._handle_main_loop_exception): + self._trio.run(self._main_task, instruments=[emulate_idle_callbacks]) + + async def run_async(self): + """Starts the main loop and blocks asynchronously until the main loop + exits. This allows one to embed an urwid app in a Trio app even if the + Trio event loop is already running. Example:: + + with trio.open_nursery() as nursery: + event_loop = urwid.TrioEventLoop(nursery=nursery) + loop = urwid.MainLoop(widget, event_loop=event_loop) + with loop.start(): + await event_loop.run_async() + """ + idle_callbacks = self._idle_callbacks + + # This class is duplicated in run_async(). It would be nice to move + # this somewhere outside, but we cannot do it yet becase we need to + # derive it from self._trio.abc.Instrument class TrioIdleCallbackInstrument(self._trio.abc.Instrument): def before_io_wait(self, timeout): if timeout > 0: @@ -138,15 +155,12 @@ emulate_idle_callbacks = TrioIdleCallbackInstrument() - with self._trio.MultiError.catch(_exception_handler): - if not self._nursery: - self._trio.run(self._main_task, instruments=[emulate_idle_callbacks]) - else: - self._trio.hazmat.add_instrument(emulate_idle_callbacks) - try: - self._nursery.start_soon(self._main_task) - finally: - self._trio.hazmat.remove_instrument(emulate_idle_callbacks) + with self._trio.MultiError.catch(self._handle_main_loop_exception): + self._trio.hazmat.add_instrument(emulate_idle_callbacks) + try: + await self._main_task() + finally: + self._trio.hazmat.remove_instrument(emulate_idle_callbacks) def watch_file(self, fd, callback): """Calls `callback()` when the given file descriptor has some data @@ -174,21 +188,30 @@ await self._sleep(seconds) callback() + def _handle_main_loop_exception(self, exc): + """Handles exceptions raised from the main loop, catching ExitMainLoop + instead of letting it propagate through. + + Note that since Trio may collect multiple exceptions from tasks into a + Trio MultiError, we cannot simply use a try..catch clause, we need a + helper function like this. + """ + self._idle_callbacks.clear() + if isinstance(exc, ExitMainLoop): + return None + else: + return exc + async def _main_task(self): """Main Trio task that opens a nursery and then sleeps until the user exits the app by raising ExitMainLoop. """ - - if self._nursery: - self._schedule_pending_tasks() - await self._trio.sleep_forever() - else: - try: - async with self._trio.open_nursery() as self._nursery: - self._schedule_pending_tasks() - await self._trio.sleep_forever() - finally: - self._nursery = None + try: + async with self._trio.open_nursery() as self._nursery: + self._schedule_pending_tasks() + await self._trio.sleep_forever() + finally: + self._nursery = None def _schedule_pending_tasks(self): """Schedules all pending asynchronous tasks that were created before @@ -227,6 +250,9 @@ callback: the callback to call """ with scope: - while True: + # We check for the scope being cancelled before calling + # wait_readable because if callback cancels the scope, fd might be + # closed and calling wait_readable with a closed fd does not work. + while not scope.cancel_called: await self._wait_readable(fd) callback() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/container.py new/urwid-2.1.1/urwid/container.py --- old/urwid-2.1.0/urwid/container.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/container.py 2020-07-27 01:36:41.000000000 +0200 @@ -145,7 +145,7 @@ :param h_sep: blank columns between each cell horizontally :param v_sep: blank rows between cells vertically (if more than one row is required to display all the cells) - :param align: horizontal alignment of cells, one of\: + :param align: horizontal alignment of cells, one of: 'left', 'center', 'right', ('relative', percentage 0=left 100=right) """ self._contents = MonitoredFocusList([ @@ -370,6 +370,9 @@ if self.v_sep: # remove first divider del p.contents[:1] + else: + # Ensure p __selectable is updated + p._contents_modified() return p @@ -512,7 +515,8 @@ self.set_overlay_parameters(align, width, valign, height, min_width, min_height, left, right, top, bottom) - def options(self, align_type, align_amount, width_type, width_amount, + @staticmethod + def options(align_type, align_amount, width_type, width_amount, valign_type, valign_amount, height_type, height_amount, min_width=None, min_height=None, left=0, right=0, top=0, bottom=0): """ @@ -1382,7 +1386,8 @@ .. seealso:: Create new options tuples with the :meth:`options` method """) - def options(self, height_type=WEIGHT, height_amount=1): + @staticmethod + def options(height_type=WEIGHT, height_amount=1): """ Return a new options tuple for use in a Pile's :attr:`contents` list. @@ -1914,7 +1919,8 @@ .. seealso:: Create new options tuples with the :meth:`options` method """) - def options(self, width_type=WEIGHT, width_amount=1, box_widget=False): + @staticmethod + def options(width_type=WEIGHT, width_amount=1, box_widget=False): """ Return a new options tuple for use in a Pile's .contents list. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/display_common.py new/urwid-2.1.1/urwid/display_common.py --- old/urwid-2.1.0/urwid/display_common.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/display_common.py 2020-07-27 01:36:41.000000000 +0200 @@ -386,6 +386,20 @@ except ValueError: return None + +def _true_to_256(desc): + + if not (desc.startswith('#') and len(desc) == 7): + return None + + c256 = _parse_color_256("#" + "".join([ + format(int(x, 16)//16, "x") + for x in [desc[1:3], desc[3:5], desc[5:7] ] + ] + )) + return _color_desc_256(c256) + + def _parse_color_88(desc): """ Return a color number for the description desc. @@ -616,7 +630,7 @@ scolor = _parse_color_true(part) flags |= _FG_TRUE_COLOR else: - scolor = _parse_color_256(part) + scolor = _parse_color_256(_true_to_256(part) or part) flags |= _FG_HIGH_COLOR # _parse_color_*() return None for unrecognised colors if scolor is None: @@ -658,7 +672,7 @@ color = _parse_color_true(background) flags |= _BG_TRUE_COLOR else: - color = _parse_color_256(background) + color = _parse_color_256(_true_to_256(background) or background) flags |= _BG_HIGH_COLOR if color is None: raise AttrSpecError(("Unrecognised color specification " + @@ -795,8 +809,8 @@ :meth:`_start`. """ if not self._started: + self._started = True self._start(*args, **kwargs) - self._started = True return StoppingContext(self) def _start(self): @@ -920,6 +934,8 @@ foreground_high = foreground if background_high is None: background_high = background + + high_256 = AttrSpec(foreground_high, background_high, 256) high_true = AttrSpec(foreground_high, background_high, 2**24) # 'hX' where X > 15 are different in 88/256 color, use @@ -938,8 +954,8 @@ high_88 = AttrSpec(foreground_high, background_high, 88) signals.emit_signal(self, UPDATE_PALETTE_ENTRY, - name, basic, mono, high_88, high_true) - self._palette[name] = (basic, mono, high_88, high_true) + name, basic, mono, high_88, high_256, high_true) + self._palette[name] = (basic, mono, high_88, high_256, high_true) def _test(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/listbox.py new/urwid-2.1.1/urwid/listbox.py --- old/urwid-2.1.0/urwid/listbox.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/listbox.py 2020-07-27 01:36:41.000000000 +0200 @@ -81,12 +81,13 @@ except (IndexError, KeyError): return None, None - class SimpleListWalker(MonitoredList, ListWalker): - def __init__(self, contents): + def __init__(self, contents, wrap_around=False): """ contents -- list to copy into this object + wrap_around -- if true, jumps to beginning/end of list on move + This class inherits :class:`MonitoredList` which means it can be treated as a list. @@ -98,6 +99,7 @@ raise ListWalkerError("SimpleListWalker expecting list like object, got: %r"%(contents,)) MonitoredList.__init__(self, contents) self.focus = 0 + self.wrap_around = wrap_around def _get_contents(self): """ @@ -138,6 +140,8 @@ Return position after start_from. """ if len(self) - 1 <= position: + if self.wrap_around: + return 0 raise IndexError return position + 1 @@ -146,6 +150,8 @@ Return position before start_from. """ if position <= 0: + if self.wrap_around: + return len(self) - 1 raise IndexError return position - 1 @@ -159,10 +165,12 @@ class SimpleFocusListWalker(ListWalker, MonitoredFocusList): - def __init__(self, contents): + def __init__(self, contents, wrap_around=False): """ contents -- list to copy into this object + wrap_around -- if true, jumps to beginning/end of list on move + This class inherits :class:`MonitoredList` which means it can be treated as a list. @@ -178,6 +186,7 @@ raise ListWalkerError("SimpleFocusListWalker expecting list like " "object, got: %r"%(contents,)) MonitoredFocusList.__init__(self, contents) + self.wrap_around = wrap_around def set_modified_callback(self, callback): """ @@ -199,6 +208,8 @@ Return position after start_from. """ if len(self) - 1 <= position: + if self.wrap_around: + return 0 raise IndexError return position + 1 @@ -207,6 +218,8 @@ Return position before start_from. """ if position <= 0: + if self.wrap_around: + return len(self) - 1 raise IndexError return position - 1 @@ -324,7 +337,7 @@ cursor = None if maxrow and focus_widget.selectable() and focus: if hasattr(focus_widget,'get_cursor_coords'): - cursor=focus_widget.get_cursor_coords((maxcol,)) + cursor = focus_widget.get_cursor_coords((maxcol,)) if cursor is not None: cx, cy = cursor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/numedit.py new/urwid-2.1.1/urwid/numedit.py --- old/urwid-2.1.0/urwid/numedit.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/numedit.py 2020-07-27 01:36:41.000000000 +0200 @@ -242,7 +242,7 @@ decimalSeparator)) val = "" - if default is not None and default is not "": + if default is not None and default != "": if not isinstance(default, (int, str, Decimal)): raise ValueError("default: Only 'str', 'int', " "'long' or Decimal input allowed") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/raw_display.py new/urwid-2.1.1/urwid/raw_display.py --- old/urwid-2.1.0/urwid/raw_display.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/raw_display.py 2020-07-27 01:36:41.000000000 +0200 @@ -101,7 +101,7 @@ def _on_update_palette_entry(self, name, *attrspecs): # copy the attribute to a dictionary containing the escape seqences - a = attrspecs[{16:0,1:1,88:2,256:3,2**24:3}[self.colors]] + a = attrspecs[{16:0,1:1,88:2,256:3,2**24:4}[self.colors]] self._pal_attrspec[name] = a self._pal_escape[name] = self._attrspec_to_escape(a) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/tests/test_container.py new/urwid-2.1.1/urwid/tests/test_container.py --- old/urwid-2.1.0/urwid/tests/test_container.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/tests/test_container.py 2020-07-27 01:36:41.000000000 +0200 @@ -1,4 +1,10 @@ import unittest +try: + # Python3 version + import unittest.mock as mock +except ImportError: + # Python2, rely on PyPi + import mock from urwid.tests.util import SelectableText import urwid @@ -288,6 +294,17 @@ gf = urwid.GridFlow([urwid.Text("test")], 10, 3, 1, "center") self.assertEqual(gf.rows((40,), False), 1) + def test_keypress_v_sep_0(self): + """ + Ensure proper keypress handling when v_sep is 0. + https://github.com/urwid/urwid/issues/387 + """ + call_back = mock.Mock() + button = urwid.Button("test", call_back) + gf = urwid.GridFlow([button], 10, 3, v_sep=0, align="center") + self.assertEqual(gf.keypress((20,), "enter"), None) + call_back.assert_called_with(button) + class WidgetSquishTest(unittest.TestCase): def wstest(self, w): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/tests/test_vterm.py new/urwid-2.1.1/urwid/tests/test_vterm.py --- old/urwid-2.1.0/urwid/tests/test_vterm.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/tests/test_vterm.py 2020-07-27 01:36:41.000000000 +0200 @@ -25,6 +25,8 @@ from itertools import dropwhile +from urwid.listbox import ListBox +from urwid.decoration import BoxAdapter from urwid import vterm from urwid import signals from urwid.compat import B @@ -102,9 +104,9 @@ def flush(self): self.write(chr(0x7f)) - def read(self, raw=False): + def read(self, raw=False, focus=False): self.term.wait_and_feed() - rendered = self.term.render(self.termsize, focus=False) + rendered = self.term.render(self.termsize, focus=focus) if raw: is_empty = lambda c: c == (None, None, B(' ')) content = list(rendered.content()) @@ -116,10 +118,10 @@ lines = [line.rstrip() for line in content] return B('\n').join(lines).rstrip() - def expect(self, what, desc=None, raw=False): + def expect(self, what, desc=None, raw=False, focus=False): if not isinstance(what, list): what = B(what) - got = self.read(raw=raw) + got = self.read(raw=raw, focus=focus) if desc is None: desc = '' else: @@ -243,6 +245,26 @@ self.write('\e[?6h\e[10;20r\e[10f1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\e[faa') self.expect('\n' * 9 + 'aa\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12') + def test_scrolling_region_simple_with_focus(self): + self.write('\e[10;20r\e[10f1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\e[faa') + self.expect('aa' + '\n' * 9 + '2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12', focus=True) + + def test_scrolling_region_reverse_with_focus(self): + self.write('\e[2J\e[1;2r\e[5Baaa\r\eM\eM\eMbbb\nXXX') + self.expect('\n\nbbb\nXXX\n\naaa', focus=True) + + def test_scrolling_region_move_with_focus(self): + self.write('\e[10;20r\e[2J\e[10Bfoo\rbar\rblah\rmooh\r\e[10Aone\r\eM\eMtwo\r\eM\eMthree\r\eM\eMa') + self.expect('ahree\n\n\n\n\n\n\n\n\n\nmooh', focus=True) + + def test_scrolling_twice_with_focus(self): + self.write('\e[?6h\e[10;20r\e[2;5rtest') + self.expect('\ntest', focus=True) + + def test_cursor_scrolling_region_with_focus(self): + self.write('\e[?6h\e[10;20r\e[10f1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\e[faa') + self.expect('\n' * 9 + 'aa\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12', focus=True) + def test_relative_region_jump(self): self.write('\e[21H---\e[10;20r\e[?6h\e[18Htest') self.expect('\n' * 19 + 'test\n---') @@ -267,10 +289,10 @@ def test_cursor_visibility(self): self.write('\e[?25linvisible') - self.expect('invisible') + self.expect('invisible', focus=True) self.assertEqual(self.term.term.cursor, None) self.write('\rvisible\e[?25h\e[K') - self.expect('visible') + self.expect('visible', focus=True) self.assertNotEqual(self.term.term.cursor, None) def test_get_utf8_len(self): @@ -344,3 +366,7 @@ self.expect('test2') self.expect_signal('caps_lock') self.disconnect_signal('leds') + + def test_in_listbox(self): + listbox = ListBox([BoxAdapter(self.term, 80)]) + rendered = listbox.render((80, 24)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/version.py new/urwid-2.1.1/urwid/version.py --- old/urwid-2.1.0/urwid/version.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/version.py 2020-07-27 01:36:41.000000000 +0200 @@ -1,4 +1,4 @@ from __future__ import division, print_function -VERSION = (2, 1, 0) +VERSION = (2, 1, 1) __version__ = ''.join(['-.'[type(x) == int]+str(x) for x in VERSION])[1:] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid/vterm.py new/urwid-2.1.1/urwid/vterm.py --- old/urwid-2.1.0/urwid/vterm.py 2019-11-14 00:32:36.000000000 +0100 +++ new/urwid-2.1.1/urwid/vterm.py 2020-07-27 01:36:41.000000000 +0200 @@ -247,6 +247,7 @@ self.width, self.height = width, height self.widget = widget self.modes = widget.term_modes + self.has_focus = False self.scrollback_buffer = TermScroller() self.scrolling_up = 0 @@ -270,7 +271,9 @@ self.term_cursor = self.constrain_coords(x, y) - if self.modes.visible_cursor and self.scrolling_up < self.height - y: + if self.has_focus \ + and self.modes.visible_cursor \ + and self.scrolling_up < self.height - y: self.cursor = (x, y + self.scrolling_up) else: self.cursor = None @@ -1319,6 +1322,7 @@ return [self.cols()]*self.rows() return self.content() + class Terminal(Widget): _selectable = True _sizing = frozenset([BOX]) @@ -1326,48 +1330,45 @@ signals = ['closed', 'beep', 'leds', 'title'] def __init__(self, command, env=None, main_loop=None, escape_sequence=None, - encoding='ascii'): + encoding='utf-8'): """ A terminal emulator within a widget. - 'command' is the command to execute inside the terminal, provided as a + ``command`` is the command to execute inside the terminal, provided as a list of the command followed by its arguments. If 'command' is None, the command is the current user's shell. You can also provide a callable instead of a command, which will be executed in the subprocess. - 'env' can be used to pass custom environment variables. If omitted, + ``env`` can be used to pass custom environment variables. If omitted, os.environ is used. - 'main_loop' should be provided, because the canvas state machine needs + ``main_loop`` should be provided, because the canvas state machine needs to act on input from the PTY master device. This object must have watch_file and remove_watch_file methods. - 'escape_sequence' is the urwid key symbol which should be used to break - out of the terminal widget. If it's not specified, "ctrl a" is used. + ``escape_sequence`` is the urwid key symbol which should be used to break + out of the terminal widget. If it's not specified, ``ctrl a`` is used. - 'encoding' specifies the encoding that is being used when local - keypresses in Unicode are encoded into raw bytes. The default encoding - is 'ascii' for backwards compatibility with urwid versions <= 2.0.1. - Set this to the encoding of your terminal (typically 'utf8') if you - want to be able to transmit non-ASCII characters to the spawned process. + ``encoding`` specifies the encoding that is being used when local + keypresses in Unicode are encoded into raw bytes. UTF-8 is used by default. + Set this to the encoding of your terminal if you need to transmit + characters to the spawned process in non-UTF8 encoding. Applies to Python 3.x only. + + .. note:: + + If you notice your Terminal instance is not printing unicode glyphs + correctly, make sure the global encoding for urwid is set to + ``utf8`` with ``urwid.set_encoding("utf8")``. See + :ref:`text-encodings` for more details. """ - self.__super.__init__() + Widget.__init__(self) - if escape_sequence is None: - self.escape_sequence = "ctrl a" - else: - self.escape_sequence = escape_sequence + self.escape_sequence = escape_sequence or "ctrl a" - if env is None: - self.env = dict(os.environ) - else: - self.env = dict(env) + self.env = dict(env or os.environ) - if command is None: - self.command = [self.env.get('SHELL', '/bin/sh')] - else: - self.command = command + self.command = command or [self.env.get('SHELL', '/bin/sh')] self.encoding = encoding @@ -1389,6 +1390,28 @@ self.has_focus = False self.terminated = False + def get_cursor_coords(self, size): + """Return the cursor coordinates for this terminal + """ + if self.term is None: + return None + + # temporarily set width/height to figure out the new cursor position + # given the provided width/height + orig_width, orig_height = self.term.width, self.term.height + + self.term.width = size[0] + self.term.height = size[1] + + x, y = self.term.constrain_coords( + self.term.term_cursor[0], + self.term.term_cursor[1], + ) + + self.term.width, self.term.height = orig_width, orig_height + + return (x, y) + def spawn(self): env = self.env env['TERM'] = 'linux' @@ -1492,16 +1515,21 @@ """ Ignore SIGINT if this widget has focus. """ - if self.terminated or self.has_focus == has_focus: + if self.terminated: return self.has_focus = has_focus + if self.term is not None: + self.term.has_focus = has_focus + self.term.set_term_cursor() + if has_focus: self.old_tios = RealTerminal().tty_signal_keys() RealTerminal().tty_signal_keys(*(['undefined'] * 5)) else: - RealTerminal().tty_signal_keys(*self.old_tios) + if hasattr(self, "old_tios"): + RealTerminal().tty_signal_keys(*self.old_tios) def render(self, size, focus=False): if not self.terminated: @@ -1518,18 +1546,13 @@ def add_watch(self): if self.main_loop is None: return - self.main_loop.watch_file(self.master, self.feed) def remove_watch(self): if self.main_loop is None: return - self.main_loop.remove_watch_file(self.master) - def selectable(self): - return True - def wait_and_feed(self, timeout=1.0): while True: try: @@ -1546,14 +1569,14 @@ try: data = os.read(self.master, 4096) except OSError as e: - if e.errno == 5: # End Of File + if e.errno == 5: # EIO, child terminated data = EOF elif e.errno == errno.EWOULDBLOCK: # empty buffer return else: raise - if data == EOF: # EOF on BSD + if data == EOF: self.terminate() self._emit('closed') return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urwid-2.1.0/urwid.egg-info/PKG-INFO new/urwid-2.1.1/urwid.egg-info/PKG-INFO --- old/urwid-2.1.0/urwid.egg-info/PKG-INFO 2019-11-14 18:02:20.000000000 +0100 +++ new/urwid-2.1.1/urwid.egg-info/PKG-INFO 2020-07-27 01:36:42.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: urwid -Version: 2.1.0 +Version: 2.1.1 Summary: A full-featured console (xterm et al.) user interface library Home-page: http://urwid.org/ Author: Ian Ward @@ -22,7 +22,7 @@ - Display modules include raw, curses, and experimental LCD and web displays - Support for UTF-8, simple 8-bit and CJK encodings - 24-bit (true color), 256 color, and 88 color mode support - - Compatible with Python 2.7, 3.4+ and PyPy + - Compatible with Python 2.7, 3.5+ and PyPy Home Page: http://urwid.org/ @@ -61,7 +61,6 @@ ========================= - 2.7 - - 3.4 - 3.5 - 3.6 - 3.7 @@ -83,68 +82,126 @@ `tonycpsu <//github.com/tonycpsu>`_, `ulidtko <//github.com/ulidtko>`_ - Contributors - ------------ + Authors + ------- - `aathan <//github.com/aathan>`_, `abadger <//github.com/abadger>`_, `aglyzov <//github.com/aglyzov>`_, + `agrenott <//github.com/agrenott>`_, `akosthekiss <//github.com/akosthekiss>`_, `alexozer <//github.com/alexozer>`_, + `alobbs <//github.com/alobbs>`_, + `and-semakin <//github.com/and-semakin>`_, `andersk <//github.com/andersk>`_, + `andrewshadura <//github.com/andrewshadura>`_, `aszlig <//github.com/aszlig>`_, - `atsampson <//github.com/atsampson>`_, `BkPHcgQL3V <//github.com/BkPHcgQL3V>`_, - `BlindB0 <//github.com/BlindB0>`_, - `bukzor <//github.com/bukzor>`_, + `carlos-jenkins <//github.com/carlos-jenkins>`_, + `d0c-s4vage <//github.com/d0c-s4vage>`_, + `dnaeon <//github.com/dnaeon>`_, + `drestebon <//github.com/drestebon>`_, + `EdwardBetts <//github.com/EdwardBetts>`_, `eevee <//github.com/eevee>`_, + `elenril <//github.com/elenril>`_, + `extempore <//github.com/extempore>`_, + `fabiand <//github.com/fabiand>`_, `federicotdn <//github.com/federicotdn>`_, + `floppym <//github.com/floppym>`_, `garrison <//github.com/garrison>`_, `geier <//github.com/geier>`_, - `grugq <//github.com/grugq>`_, - `hkoof <//github.com/hkoof>`_, + `grzaks <//github.com/grzaks>`_, `hootnot <//github.com/hootnot>`_, `horazont <//github.com/horazont>`_, + `ids1024 <//github.com/ids1024>`_, `inducer <//github.com/inducer>`_, `ismail-s <//github.com/ismail-s>`_, - `italomaia-bk <//github.com/italomaia-bk>`_, `ivanov <//github.com/ivanov>`_, + `jeblair <//github.com/jeblair>`_, `Julian <//github.com/Julian>`_, `jwilk <//github.com/jwilk>`_, - `kajojify <//github.com/kajojify>`_, - `Kamik423 <//github.com/Kamik423>`_, + `kedder <//github.com/kedder>`_, + `KennethNielsen <//github.com/KennethNielsen>`_, `kkrolczyk <//github.com/kkrolczyk>`_, - `marienz <//github.com/marienz>`_, + `larsks <//github.com/larsks>`_, + `Lothiraldan <//github.com/Lothiraldan>`_, `matthijskooijman <//github.com/matthijskooijman>`_, + `mattymo <//github.com/mattymo>`_, `mbarkhau <//github.com/mbarkhau>`_, - `mgiusti <//github.com/mgiusti>`_, - `mikemccracken <//github.com/mikemccracken>`_, + `mgk <//github.com/mgk>`_, + `mimi1vx <//github.com/mimi1vx>`_, + `mobyte0 <//github.com/mobyte0>`_, + `mwhudson <//github.com/mwhudson>`_, + `nchavez324 <//github.com/nchavez324>`_, + `neumond <//github.com/neumond>`_, `nocarryr <//github.com/nocarryr>`_, `ntamas <//github.com/ntamas>`_, `olleolleolle <//github.com/olleolleolle>`_, `pazz <//github.com/pazz>`_, `pniedzwiedzinski <//github.com/pniedzwiedzinski>`_, `raek <//github.com/raek>`_, - `richrd <//github.com/richrd>`_, + `renegarcia <//github.com/renegarcia>`_, + `rianhunter <//github.com/rianhunter>`_, `rndusr <//github.com/rndusr>`_, - `robla <//github.com/robla>`_, `rr- <//github.com/rr->`_, - `seleem1337 <//github.com/seleem1337>`_, - `SenchoPens <//github.com/SenchoPens>`_, - `shyal <//github.com/shyal>`_, - `sitaktif <//github.com/sitaktif>`_, + `rwarren <//github.com/rwarren>`_, + `seanhussey <//github.com/seanhussey>`_, + `Sjc1000 <//github.com/Sjc1000>`_, + `ssbr <//github.com/ssbr>`_, `tdryer <//github.com/tdryer>`_, `techtonik <//github.com/techtonik>`_, + `tompickering <//github.com/tompickering>`_, `tu500 <//github.com/tu500>`_, + `uSpike <//github.com/uSpike>`_, `usrlocalben <//github.com/usrlocalben>`_, - `wackywendell <//github.com/wackywendell>`_, + `waveform80 <//github.com/waveform80>`_, `wernight <//github.com/wernight>`_, + `Wesmania <//github.com/Wesmania>`_, `westurner <//github.com/westurner>`_, - `whospal <//github.com/whospal>`_, - `Wilfred <//github.com/Wilfred>`_, `winbornejw <//github.com/winbornejw>`_, + `xndcn <//github.com/xndcn>`_, `xnox <//github.com/xnox>`_, - `yanzixiang <//github.com/yanzixiang>`_ + `zrax <//github.com/zrax>`_ + + Contributors + ------------ + + `aleufroy <//github.com/aleufroy>`_, + `andy-z <//github.com/andy-z>`_, + `anttin2020 <//github.com/anttin2020>`_, + `belak <//github.com/belak>`_, + `berney <//github.com/berney>`_, + `bk2204 <//github.com/bk2204>`_, + `bukzor <//github.com/bukzor>`_, + `Chipsterjulien <//github.com/Chipsterjulien>`_, + `chrisspen <//github.com/chrisspen>`_, + `dimays <//github.com/dimays>`_, + `dlo <//github.com/dlo>`_, + `douglas-larocca <//github.com/douglas-larocca>`_, + `goncalopp <//github.com/goncalopp>`_, + `Gordin <//github.com/Gordin>`_, + `grugq <//github.com/grugq>`_, + `hkoof <//github.com/hkoof>`_, + `Hoolean <//github.com/Hoolean>`_, + `hukka <//github.com/hukka>`_, + `itaisod <//github.com/itaisod>`_, + `ixxra <//github.com/ixxra>`_, + `Kelketek <//github.com/Kelketek>`_, + `livibetter <//github.com/livibetter>`_, + `marlox-ouda <//github.com/marlox-ouda>`_, + `MonAaraj <//github.com/MonAaraj>`_, + `mountainstorm <//github.com/mountainstorm>`_, + `mselee <//github.com/mselee>`_, + `nyov <//github.com/nyov>`_, + `pquentin <//github.com/pquentin>`_, + `RRMoelker <//github.com/RRMoelker>`_, + `shadedKE <//github.com/shadedKE>`_, + `sitaktif <//github.com/sitaktif>`_, + `sporkexec <//github.com/sporkexec>`_, + `thehunmonkgroup <//github.com/thehunmonkgroup>`_, + `thisch <//github.com/thisch>`_, + `TomasTomecek <//github.com/TomasTomecek>`_, + `ttanner <//github.com/ttanner>`_, + `vega0 <//github.com/vega0>`_ .. |pypi| image:: http://img.shields.io/pypi/v/urwid.svg @@ -178,7 +235,6 @@ Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7