Code Monkey home page Code Monkey logo

yaspin's Introduction

yaspin Logo

yaspin: Yet Another Terminal Spinner for Python

Coverage pypi black-fmt

Versions Wheel Examples

DownloadsTot DownloadsW

Yaspin provides a full-featured terminal spinner to show the progress during long-hanging operations.

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/demo.gif

It is easy to integrate into existing codebase by using it as a context manager or as a function decorator:

import time
from yaspin import yaspin

# Context manager:
with yaspin():
    time.sleep(3)  # time consuming code

# Function decorator:
@yaspin(text="Loading...")
def some_operations():
    time.sleep(3)  # time consuming code

some_operations()

Yaspin also provides an intuitive and powerful API. For example, you can easily summon a shark:

import time
from yaspin import yaspin

with yaspin().white.bold.shark.on_blue as sp:
    sp.text = "White bold shark in a blue sea"
    time.sleep(5)

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/shark.gif

Features

  • Runs at all major CPython versions (3.9, 3.10, 3.11, 3.12), PyPy
  • Supports all (70+) spinners from cli-spinners
  • Supports all colors, highlights, attributes and their mixes from termcolor library
  • Easy to combine with other command-line libraries, e.g. prompt-toolkit
  • Flexible API, easy to integrate with existing code
  • User-friendly API for handling POSIX signals
  • Safe pipes and redirects:
$ python script_that_uses_yaspin.py > script.log
$ python script_that_uses_yaspin.py | grep ERROR

Installation

From PyPI using pip package manager:

pip install --upgrade yaspin

Or install the latest sources from GitHub:

pip install https://github.com/pavdmyt/yaspin/archive/master.zip

Usage

Basic Example

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/basic_example.gif

import time
from random import randint
from yaspin import yaspin

with yaspin(text="Loading", color="yellow") as spinner:
    time.sleep(2)  # time consuming code

    success = randint(0, 1)
    if success:
        spinner.ok("✅ ")
    else:
        spinner.fail("💥 ")

It is also possible to control spinner manually:

import time
from yaspin import yaspin

spinner = yaspin()
spinner.start()

time.sleep(3)  # time consuming tasks

spinner.stop()

Run any spinner from cli-spinners

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/cli_spinners.gif

import time
from yaspin import yaspin
from yaspin.spinners import Spinners

with yaspin(Spinners.earth, text="Earth") as sp:
    time.sleep(2)                # time consuming code

    # change spinner
    sp.spinner = Spinners.moon
    sp.text = "Moon"

    time.sleep(2)                # time consuming code

Any Colour You Like 🌈

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/basic_colors.gif

import time
from yaspin import yaspin

with yaspin(text="Colors!") as sp:
    # Support all basic termcolor text colors
    colors = ("red", "green", "yellow", "blue", "magenta", "cyan", "white")

    for color in colors:
        sp.color, sp.text = color, color
        time.sleep(1)

Advanced colors usage

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/advanced_colors.gif

import time
from yaspin import yaspin
from yaspin.spinners import Spinners

text = "Bold blink magenta spinner on cyan color"
with yaspin().bold.blink.magenta.bouncingBall.on_cyan as sp:
    sp.text = text
    time.sleep(3)

# The same result can be achieved by passing arguments directly
with yaspin(
    Spinners.bouncingBall,
    color="magenta",
    on_color="on_cyan",
    attrs=["bold", "blink"],
) as sp:
    sp.text = text
    time.sleep(3)

Run any spinner you want

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/custom_spinners.gif

import time
from yaspin import yaspin, Spinner

# Compose new spinners with custom frame sequence and interval value
sp = Spinner(["😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀"], 200)

with yaspin(sp, text="Cat!"):
    time.sleep(3)  # cat consuming code :)

Change spinner properties on the fly

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/sp_properties.gif

import time
from yaspin import yaspin
from yaspin.spinners import Spinners

with yaspin(Spinners.noise, text="Noise spinner") as sp:
    time.sleep(2)

    sp.spinner = Spinners.arc  # spinner type
    sp.text = "Arc spinner"    # text along with spinner
    sp.color = "green"         # spinner color
    sp.side = "right"          # put spinner to the right
    sp.reversal = True         # reverse spin direction

    time.sleep(2)

Spinner with timer

import time
from yaspin import yaspin

with yaspin(text="elapsed time", timer=True) as sp:
    time.sleep(3.1415)
    sp.ok()

Dynamic text

import time
from datetime import datetime
from yaspin import yaspin

class TimedText:
    def __init__(self, text):
        self.text = text
        self._start = datetime.now()

    def __str__(self):
        now = datetime.now()
        delta = now - self._start
        return f"{self.text} ({round(delta.total_seconds(), 1)}s)"

with yaspin(text=TimedText("time passed:")):
    time.sleep(3)

Writing messages

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/write_text.gif

You should not write any message in the terminal using print while spinner is open. To write messages in the terminal without any collision with yaspin spinner, a .write() method is provided:

import time
from yaspin import yaspin

with yaspin(text="Downloading images", color="cyan") as sp:
    # task 1
    time.sleep(1)
    sp.write("> image 1 download complete")

    # task 2
    time.sleep(2)
    sp.write("> image 2 download complete")

    # finalize
    sp.ok("✔")

Integration with other libraries

https://raw.githubusercontent.com/pavdmyt/yaspin/master/gifs/hide_show.gif

Utilizing hidden context manager it is possible to toggle the display of the spinner in order to call custom methods that write to the terminal. This is helpful for allowing easy usage in other frameworks like prompt-toolkit. Using the powerful print_formatted_text function allows you even to apply HTML formats and CSS styles to the output:

import sys
import time

from yaspin import yaspin
from prompt_toolkit import HTML, print_formatted_text
from prompt_toolkit.styles import Style

# override print with feature-rich ``print_formatted_text`` from prompt_toolkit
print = print_formatted_text

# build a basic prompt_toolkit style for styling the HTML wrapped text
style = Style.from_dict({
    'msg': '#4caf50 bold',
    'sub-msg': '#616161 italic'
})


with yaspin(text='Downloading images') as sp:
    # task 1
    time.sleep(1)
    with sp.hidden():
        print(HTML(
            u'<b>></b> <msg>image 1</msg> <sub-msg>download complete</sub-msg>'
        ), style=style)

    # task 2
    time.sleep(2)
    with sp.hidden():
        print(HTML(
            u'<b>></b> <msg>image 2</msg> <sub-msg>download complete</sub-msg>'
        ), style=style)

    # finalize
    sp.ok()

Handling POSIX signals

Handling keyboard interrupts (pressing Control-C):

import time

from yaspin import kbi_safe_yaspin


with kbi_safe_yaspin(text="Press Control+C to send SIGINT (Keyboard Interrupt) signal"):
    time.sleep(5)  # time consuming code

Handling other types of signals:

import os
import time
from signal import SIGTERM, SIGUSR1

from yaspin import yaspin
from yaspin.signal_handlers import default_handler, fancy_handler


sigmap = {SIGUSR1: default_handler, SIGTERM: fancy_handler}
with yaspin(sigmap=sigmap, text="Handling SIGUSR1 and SIGTERM signals") as sp:
    sp.write("Send signals using `kill` command")
    sp.write("E.g. $ kill -USR1 {0}".format(os.getpid()))
    time.sleep(20)  # time consuming code

More examples.

Development

Clone the repository:

git clone https://github.com/pavdmyt/yaspin.git

Install dev dependencies:

poetry install

# if you don't have poetry installed:
pip install -r requirements.txt

Lint code:

make lint

Format code:

make black-fmt

Run tests:

make test

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -m 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request
  6. Make sure tests are passing

License

yaspin's People

Contributors

driazati avatar eerimoq avatar frostming avatar harenbrs avatar ionite34 avatar j-m0 avatar janpipek avatar makkus avatar nchepanov avatar nschrader avatar pavdmyt avatar pyup-bot avatar sebageek avatar stephen-bunn avatar unviray avatar vilhelmprytz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yaspin's Issues

Unexpected output characters

We are using the yaspin in our library. It runs on any notebook, like jupyter or Databricks, on MacOS or Cloud based.
Generally yaspin works but some strange output even if I use your examples from the README file:
Screen_Shot_2022-01-09_at_13_16_25

so is it artifacts which I can remove?
Actually I have a problem with some number and 'h' when I use yaspin in my package.

Name not defined in 3.0

Hello, I am seeing this message:

File "[EDITED]/yaspin/core.py", line 175, in __call__
    return cast(Fn, inner)
NameError: name 'Fn' is not defined

It seems that cast requires the type to be defined outside the TYPE_CHECKING condition.
Should I post a fixing PR?

All the best,
Jan

Version 3.0, Python 3.9

pipenv's patch to prevent AttributeError in _register_signal_handlers

pipenv applies a patch to their vendored copy of tomlkit, and it seems that it has parts which belong here, but havent been raised here.

The patch is https://github.com/pypa/pipenv/blob/master/tasks/vendoring/patches/vendor/yaspin-signal-handling.patch , but only the following bit looks like it belongs here:

diff --git a/pipenv/vendor/yaspin/core.py b/pipenv/vendor/yaspin/core.py
index d01fb98e..06b8b621 100644
--- a/yaspin/core.py
+++ b/yaspin/core.py
@@ -369,11 +375,14 @@ class Yaspin(object):
         # SIGKILL cannot be caught or ignored, and the receiving
         # process cannot perform any clean-up upon receiving this
         # signal.
-        if signal.SIGKILL in self._sigmap.keys():
-            raise ValueError(
-                "Trying to set handler for SIGKILL signal. "
-                "SIGKILL cannot be cought or ignored in POSIX systems."
-            )
+        try:
+            if signal.SIGKILL in self._sigmap.keys():
+                raise ValueError(
+                    "Trying to set handler for SIGKILL signal. "
+                    "SIGKILL cannot be cought or ignored in POSIX systems."
+                )
+        except AttributeError:
+            pass
 
         for sig, sig_handler in iteritems(self._sigmap):
             # A handler for a particular signal, once set, remains

I am quite confident this is correct and needed here, as signal module documentation indicates that the list of signals in this module is host specific, and I am quite sure SIGKILL doesnt exist on Windows.

It appears the author of this part of the patch was @techalchemy .

Ideally they should be submit the patch, or someone elses should submit it with the patch author set to the correct author.

Consider switching back to `termcolor`

The original termcolor project has resurrected and providing a wheel as well, now. The termcolor-whl one, however, seems to be inactive as the open issue/pr were left unanswered for a long time.

Transitive dependency (termcolor) does not have wheel

I'm working on getting security packages to have the option of installing with only wheels (it's more secure that way), ref. Jake which means the whole dependency graph needs to have wheels

yaspin's dependency on termcolor (which has no wheels and has no maintainer, so it is hard for me to get a wheel in termcolor)

I did create a fork, termcolor-whl so you could switch to that or venderize termcolor.

Without something like that, people who depend on yaspin would have to vendorize to get around the problem.

Is there a way of custom spinners?

I am curious if you can specify custom spinners in the form of a list variable of the "frames" of the animation with the first list value the delay for the animation.

Allow write() to print non-string objects

As I have to use write() in a yaspin context instead of print() I tend to use it in a similar way. This often includes printing non-string objects. print() calls repr() automatically on anything that is not a string, whereas yaspin runs into an assertion.

Would you be open to replace that assertion with something just calling repr() on the given text? This coud also be implemented for the spinner text itself. I'd also volunteer to bring up a PR for this.

Color codes do not work in Makefile

In the Makefile, the color codes do not seem to work and do not output any color.

When running make test, the following is outputted.

\033[32;01m==> Cleaning bytecode ...\033[0m
\033[32;01m==> Linting code ...\033[0m

Add return type annotations to api

Proposal to add simple type hints for better IDE completions.

Currently the primary entry point is not annotated and resolves to Any type

def yaspin(*args, **kwargs):

Resulting in no IDE completions:
yaspin1

If annotated with the return type -> Yaspin:
yaspin2

Strange spinner behavior in windows terminal

Hello!

I have a simple multi-platform app (it's designed for windows and linux environments).
Everything works fine for bash terminal, but there is a problem when I start my app on windows.
Few firsts lines is printed with strange symbols but, after that everything is fine and my spinner appears:
app.exe > output.txt
From notepad.exe:

=�[0m message...�[K�
|�[0m message...�[K�
]�[0m message...�[K�
-�[0m message...�[K�
=�[0m message...�[K�
|�[0m message...�[K�
]�[0m message...�[K�

From notepad++:
image

Copied from terminal:

�[K�[?25hmessage...

Is there any way to fix this behavior? Can I init yaspin class with some specific values to make it work or smth?

(Please note for debugging purposes I used custom very simple spinner: =|]-)

Unittesting custom signal handlers

I have code that handles keyboard interrupts with ctrl+c:

# my_code.py

def my_signal_handler(signum, frame, spinner):
  # does some things

def run_a_long_running_command()
  with yaspin.yaspin(
        sigmap={
            signal.SIGINT: my_signal_handler
        }, color="yellow").point as spinner:
    time.sleep(10)

And a unit test (e.g. my_code_test.py) that is attempting to engage the lines in my_signal_handler() to assert something is done inside it.

But I haven't been able to make this happen when using the unittest framework. I first tried to raise a KeyboardInterrupt, but realized that signals are not an exception. I then realized that making time.sleep(10) instead do os.kill(os.getpid(), signal.SIGINT) doesn't work either. Is there a way to manually cause the signal to occur from another file?

[Question] Parallel spinners

Dear developer,

Thank you for this wonderful library. Is it possible to 'run' multiple spinners at the same time ?

Our use case is that we run multiple downloads in parallel, and would like to show a spinner for each of them.

Thank you.

Yaspin thread in daemon mode

Is there any good reason for not allowing yaspin to be spawned in daemon mode?

Why am I asking? Because if not you can't interrupt the process execution using Ctrl+C.

Thx.

Ns. Pretty amazing library I must say... sadly I can't see colored emojis using conemu on win7 :'(

redirected output has spinners

My redirected output has...

�[33m⠋�[0m �[K �[33m⠙�[0m �[K �[33m⠹�[0m �[K �[33m⠸�[0m �[K �[33m⠼�[0m �[K �[33m⠴�[0m �[K �[33m⠦�[0m �[K �[33m⠧�[0m �[K �[33m⠇�[0m �[K

Is there anyway to get rid of that?

AssertionError in Py2 if provided Spinner.frames is a bytes sequence

Consider following code:

# -*- coding: utf-8 -*-
import time
from yaspin import yaspin, Spinner

sp = Spinner(["😸", "😹", "😺", "😻", "😼", "😽", "😾", "😿", "🙀"], 200)
with yaspin(sp, text="Cat!"):
    time.sleep(3)

Running this in Python 2.7 will result in the following exception:

$ python cat_example.py
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/var/pyenv/versions/2.7.14/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "/usr/local/var/pyenv/versions/2.7.14/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/me/PY_proj/yaspin/yaspin/yaspin.py", line 184, in _spin
    out = self._compose_out(spin_phase)
  File "/Users/me/PY_proj/yaspin/yaspin/yaspin.py", line 197, in _compose_out
    assert isinstance(frame, str)
AssertionError

Initial Update

The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.

Race condition between spinner thread and write()

When I use write() a lot on a spinner it often happens to me that the written text is displayed after the spinner message, like this:

[...]
noot noot
⠋ spinning...noot noot
noot noot
[...]

I used the script below to recreate the problem. It takes some time (400-800 writes) with it, but happens to me far more often with real world applications.

import random
import time

import yaspin

with yaspin.yaspin() as sp:
    sp.text = 'spinning...'
    while True:
        sp.write('noot noot')
        time.sleep(0.051 + random.randint(0, 10) / 100)

I think this happens because of concurrent access to sys.stdout.write() by the spinning thread and the spinners write(). This should be solvable by using a threading.Lock() and guarding access to sys.stdout.write() with it. In a quick local hack-fix-test it worked for me by doing this in write() and _spin(), but there are a lot more functions that would need guarding, if done right.

Scroll the terminal while the spinner spins

While the spinner is spinning, I can't scroll the terminal to read the previously printed lines (the spinner constantly brings me back to the last line). Is there a way around that ?

yaspin with pyinstaller

Hello,
I use yaspin in my code. Thanks a lot!
I want to make my program executable with pyinstaller but the spinners are only cryptically displayed. Do I have to provide the pyinstaller with more data from yaspin?

Wierd print on windows terminal

When i use the yaspin function, on the pure windows terminal I get ⠦←[0m Loading...←[K←[?25h instead of a loading spinner.

Release plan

Hello!

When do you plan to create another release?

Writes to stdout during hidden state of the spinner should be flushed somehow

Writes to stdout when spinner is in hidden state (using Yaspin.hide) should explicitly contain a newline character \n in order to flush the stdout. Consider this example:

import sys
import time

from yaspin import yaspin

with yaspin(text='Downloading images') as sp:
    # task 1
    time.sleep(1)
    sp.hide()
    sys.stdout.write('> image 1 download complete\n')
    sp.show()

    # task 2
    time.sleep(2)
    sp.hide()
    sys.stdout.write('> image 2 download complete\n')
    sp.show()

It is desirable that library handles this by itself. One of the possible approach is to monitor stdout of the process which utilizes yaspin. Here some relevant discussions I've found:

Somewhat similar functionality is also implemented in capsys fixture from pytest.

Yaspin pipesafety issues

Pipesafety of yaspin does not work for me (or I misunderstood the feature).

When I run yaspin and pipe the output into another program or into a file I'd expect to only see the output of write() calls and maybe of ok()/fail() or other functions with persistant text. Nevertheless I can also see the spinnerstate in programms like less or xxd.

import time
import yaspin

with yaspin.yaspin() as sp:
    sp.text = 'Test'
    time.sleep(0.25)
    sp.write('Hello world')

and when running this script

$ python pipesafe.py |xxd
00000000: 0de2 a08b 1b5b 306d 201b 5b4b 080d e2a0  .....[0m .[K....
00000010: 991b 5b30 6d20 5465 7374 1b5b 4b08 0de2  ..[0m Test.[K...
00000020: a0b9 1b5b 306d 2054 6573 741b 5b4b 080d  ...[0m Test.[K..
00000030: e2a0 b81b 5b30 6d20 5465 7374 1b5b 4b0d  ....[0m Test.[K.
00000040: 1b5b 4b48 656c 6c6f 2077 6f72 6c64 0a08  .[KHello world..
00000050: 0d1b 5b4b                                ..[K

This feels especially weird when using grep. In the case grep matches the spinner text, only the text from write() is displayed:

$ python pipesafe.py | grep Test
Hello world

$ python pipesafe.py | grep Test | xxd
00000000: 0de2 a08b 1b5b 306d 201b 5b4b 080d e2a0  .....[0m .[K....
00000010: 991b 5b30 6d20 5465 7374 1b5b 4b08 0de2  ..[0m Test.[K...
00000020: a0b9 1b5b 306d 2054 6573 741b 5b4b 080d  ...[0m Test.[K..
00000030: e2a0 b81b 5b30 6d20 5465 7374 1b5b 4b0d  ....[0m Test.[K.
00000040: 1b5b 4b48 656c 6c6f 2077 6f72 6c64 0a    .[KHello world.

In an attempt to fix this in an application I'm writing I created a yaspin-like interface, that maps write() to print() and ignores .text plus all other calls to the class. I then replace yaspin with that class if stdout is not a tty, but I'm not sure if this is the way to go for upstream.

write() method and leading whitespace

I'm trying to use the spinner.write() method to output sorta hierarchical text, but that proves difficult as it strips every input string (here:

_text = to_unicode(text).strip()
).

Is there a reason for this, or could this strip() command be removed? I'd be also happy with an option that defaults to strip, but lets me disable it. It's a trivial change, but I'd be happy to provide a pull request if necessary, and if my proposed change is acceptable.

Correct `pyproject.toml` build-backend specification

Currently:

yaspin/pyproject.toml

Lines 75 to 77 in 2c78d24

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

According to https://python-poetry.org/docs/pyproject/#poetry-and-pep-517

If your pyproject.toml file still references poetry directly as a build backend, you should update it to reference poetry_core instead.

Should be updated to,

[build-system]
requires = ["poetry_core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

This will significantly speed up the package installation process, since the entire poetry dependency cone is currently being installed during isolated build per PEP517.

I can submit a PR if no objections.

Fail to show unicode symbols > 0xffff under Python 2 narrow builds

Python 2 narrow build raises ValueError for unicode characters greater than 0xffff:

Python 2.7.13 (default, Jan 18 2017, 11:00:40)
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> unichr(0xffff + 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unichr() arg not in range(0x10000) (narrow Python build)

Following code snippet does not fail but prints ��� (gibberish) into a terminal:

# -*- coding: utf-8 -*-

import time
from yaspin import yaspin, Spinner

sp = Spinner("😸😹😺😻😼😽😾😿🙀", 200)
with yaspin(sp, text="Cat!"):
    time.sleep(2)

During iteration over "😸😹😺😻😼😽😾😿🙀" sequence narrow build Python represents unicode characters above u+ffff as two codepoints.

More info on narrow Python:
http://wordaligned.org/articles/narrow-python
https://stackoverflow.com/questions/46711888/how-to-properly-iterate-over-unicode-characters-in-python

Windows support

In continuation to discussion on windows support for yaspin started in #32

Minimum plan towards Windows support:

  • apply the patch for handling signals
  • use vistir/cursor module for cursor support
  • implement (or find the replacement for) termcolor features in Windows environment
  • unittests for all yaspin features under Windows
  • CI pipeline for tests under Windows

Fails on PYTHONOPTIMIZE=2

Versions:

yaspin 0.14
python 3.7

Env variables:

PYTHONOPTIMIZE=2

Traceback

10 99.05 Traceback (most recent call last):
#10 99.05   File "/usr/local/bin/pipenv", line 7, in <module>
#10 99.05     from pipenv import cli
#10 99.05   File "/usr/local/lib/python3.7/site-packages/pipenv/__init__.py", line 22, in <module>
#10 99.05     from pipenv.vendor.vistir.compat import ResourceWarning, fs_str
#10 99.05   File "/usr/local/lib/python3.7/site-packages/pipenv/vendor/vistir/__init__.py", line 31, in <module>
#10 99.05     from .spin import VistirSpinner, create_spinner
#10 99.05   File "/usr/local/lib/python3.7/site-packages/pipenv/vendor/vistir/spin.py", line 19, in <module>
#10 99.05     import yaspin
#10 99.05   File "/usr/local/lib/python3.7/site-packages/pipenv/vendor/yaspin/__init__.py", line 6, in <module>
#10 99.05     from .api import kbi_safe_yaspin, yaspin
#10 99.05   File "/usr/local/lib/python3.7/site-packages/pipenv/vendor/yaspin/api.py", line 87, in <module>
#10 99.05     _kbi_safe_doc = yaspin.__doc__.replace("yaspin", "kbi_safe_yaspin")
#10 99.05 AttributeError: 'NoneType' object has no attribute 'replace'

Consider a conda package

We'd like to use yaspin but we use conda environments. It is possible to install pypi packages into conda environments, but you can end up with unpredictable and unsatisfiable dependencies.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.