Git Product home page Git Product logo

amogorkon / justuse Goto Github PK

View Code? Open in Web Editor NEW
49.0 4.0 8.0 36.94 MB

Just use() code from anywhere - a functional import alternative with advanced features like inline version checks, autoreload, module globals injection before import and more.

License: MIT License

Python 92.40% Shell 2.03% HTML 3.58% CSS 1.99%
import python38 hot-reload auto-install pythonic functional aspect-oriented-programming

justuse's Introduction

license stars Maintenance Updates Build Downloads justuse slack codecov Sourcery Code style: black

Just use() python the way you want!

graph TD;
    A[just]-->B["use()"];
    B --> C["Path()"]
    B --> D["URL()"]
    B --> E[packages]
    B --> F[git]
Loading

Installation

To install, enter python -m pip install justuse in a commandline, then you can import use in your code and simply use() stuff. Check for examples below and our Showcase!

Features, Claims & Goals

  • inline version-checking
  • safely import code from an online URL - towards an unhackable infrastructure ("Rather die than get corrupted!")
  • initial module globals - a straight forward solution to diamond/cyclic imports
  • decorate everything callable recursively via pattern matching, aspect-orientation made easy (except closures, those are hard)
  • return a given default if an exception happened during an import, simplifying optional dependencies
  • safe hot auto-reloading of function-only local modules - a REPL-like dev experience with files in jupyter and regular python interpreters
  • signature compatibility checks for all callables in hot reloading modules as a first line of defense against invading bugs
  • safely auto-install version-tagged pure python packages from PyPI
  • have multiple versions of the same package installed and loaded in the same program without conflicts
  • auto-install packages with C-extensions and other precompiled stuff
  • no-hassle inline auto-installation of (almost) all conda packages
  • install packages directly from github with signature compatibility check for all callables
  • attach birdseye debugger to a loaded module as a mode
  • try to pull packages from a P2P network before pulling from PyPI or conda directly
  • all justuse-code is compiled to a single, standalone .py file - just drop it into your own code without installation
  • provide a visual representation of the internal dependency graph
  • module-level variable guards aka "module-properties"
  • isolation of software components with arbitrary sub-interpreters (python 2.7, ironpython..) inspired by jupyter messaging
  • slot-based plugin architecture (to ensure reproducable testability of plugin-combinations)
  • optional on-site compilation of fully annotated python code via cython
  • document everything!
  • test everything!

The Story

Over the years, many times I've come across various situations where Python's import statement just didn't work the way I needed. There were projects where I felt that a central module from where to expand functionality would be the simplest, most elegant approach, but that would only work with simple modules and libs, not with functionality that required access to the main state of the application. In those situations the first thing to try would be "import B" in module A and "import A" in module B - a classical circular import, which comes with a lot of headaches and often results in overly convoluted code. All this could be simplified if it was possible to pass some module-level global variables to the about-to-be-imported module before its actual execution, but how the heck could that work with an import statement?

Later, I worked and experimented a lot in jupyter notebooks. Usually I would have some regular python module only with pure functions open in an editor, import that module in jupyter and have all the state there. Most of the time I'd spend in jupyter, but from time to time I'd edit the file and have to manually reload the module in jupyter - why couldn't it just automatically reload the module when my file is saved? Also, in the past reload() was a builtin function, now I have to import it extra from importlib, another hoop to jump through..

Then there were situations where I found a cool module on github, a single file in a package I wanted to import - but why is it necessary to download it manually or maybe pip install an outdated package? Shouldn't it be possible to import just this exact file and somehow make it secure enough that I don't have to worry about man-in-the-middle attacks or some github-hack?

On my journey I came across many blogposts, papers and presentation-notebooks with code that just 'import library' but mentions nowhere which actual version is being used, so trying to copy and paste this code in order to reproduce the presented experiment or solution is doomed to failure.

I also remember how I had some code in a jupyter notebook that did 'import opencv' but I had not noted which actual version I had initially used. When I tried to run this notebook after a year again, it failed in a subtle way: the call signature of an opencv-function had slightly changed. It took quite a while to track down what my code was expecting and when this change occured until I figured out how to fix this issue. This could've been avoided or at least made a lot simpler if my imports were somehow annotated and checked in a pythonic way. After I complained about this in IRC, nedbat suggested an alternative functional way for imports with assignments: mod = import("name", version) which I found very alien and cumbersome at first sight - after all, we have an import statement for imports, and there should be one and preferrably only one way to do it - right?

Well, those shortcomings of the import statement kept bugging me. And when I stumbled over the word 'use' as a name for whatever I was conceiving, I thought "what the heck, let's try it! - how hard could it be?!" Turns out, some challenges like actual, working hot-reloading are pretty hard! But by now use() can cover all the original usecases and there's even more to come!

Examples

Here are a few tidbits on how to use() stuff to wet your appetite, for a more in-depth overview, check out our Showcase!

import use

np = use("numpy", version="1.19.2") corresponds to import numpy as np; if np.version != "1.19.2": warn()

use("pprint").pprint(some_dict) corresponds to a one-off from pprint import pprint; pprint(some_dict) without importing it into the global namespace

tools = use(use.Path("/media/sf_Dropbox/code/tools.py"), reloading=True) impossible to realize with classical imports

test = use("functions", initial_globals={"foo":34, "bar":49}) also impossible with the classical import statement, although importlib can help

utils = use(use.URL("https://raw.githubusercontent.com/PIA-Group/BioSPPy/7696d682dc3aafc898cd9161f946ea87db4fed7f/biosppy/utils.py"), hashes={"95f98f25ef8cfa0102642ea5babbe6dde3e3a19d411db9164af53a9b4cdcccd8"}) no chance with classical imports

np = use("numpy", version="1.21.0rc2", hashes={"3c90b0bb77615bda5e007cfa4c53eb6097ecc82e247726e0eb138fcda769b45d"}, modes=use.auto_install) inline installation of packages and importing the same package with different versions in parallel in the same code - most people wouldn't even dream of that!

There are strange chinese symbols in my hashes, am I being hacked?

Nope. SHA256 hashes normally are pretty long (64 characters per hexdigest) and we require them defined within regular python code. Additionally, if you want to support multiple platforms, you need to supply a hash for every platform - which can add up to huge blocks of visual noise. Since Python 3 supports unicode by default, why not use the whole range of printable characters to encode those hashes? It's easier said than done - turns out emojis don't work well across different systems and editors - however, it is feasible to merge the Japanese, ASCII, Chinese and Korean alphabets into a single, big one we call JACK - which can be used to reliably encode those hashes in merely 18 characters. Since humans aren't supposed to manually type those hashes but simply copy&paste them anyway, there is only the question how to get them if you only have hexdigests at hand for some reason. Simply do use.hexdigest_as_JACK(H) and you're ready to go. Of course we also support classical hexdigests as fallback.

Beware of Magic!

Inspired by the q package/module, use() is a subclass of ModuleType, which is a callable class that replaces the module on import, so that only 'import use' is needed to be able to call use() on things.

Probably the most magical thing about use() is that it does not return the plain module you wanted but a ProxyModule instead which adds a layer of abstraction. This allows things like automatic and transparent reloading without any intervention needed on your part. ProxyModules also add operations on modules like aspectizing via mod @ (check, pattern, decorator) syntax, which would not be possible with the classical import machinery.

justuse's People

Contributors

amogorkon avatar coderatul avatar ghandic avatar greyblue9 avatar pancakelord1 avatar pyup-bot avatar snyk-bot avatar sourcery-ai-bot avatar sourcery-ai[bot] avatar thirteenpylons 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

Watchers

 avatar  avatar  avatar  avatar

justuse's Issues

use() should refuse to import a str name of a valid local module

While classical import tries to guess what the user wants to do when passed a name of a local module, use() should refuse the temptation to guess and throw an exception if the passed str is not a name from an installed package like
"ImportError: No installed package with name {name} found, did you mean use(use.Path("{name}.py"}))?"
Which will teach people to distinguish between installed packages and local modules, pushing them to move from relative imports to relative Paths, which is much more flexible.

We should beautify exceptions that occur during zipimport to let the user know it's nothing to worry about.

sql = use("sqlalchemy", version="0.7.1", hash_value="5ef95d19c31a8cd3905c697be0a7e94e70ab1926ecd4159c3e6c1cf01fc3c492", auto_install=True)

Last executed at 2021-07-05 15:50:28 in 3.49s

Downloading https://files.pythonhosted.org/packages/aa/63/5ddf80758f953fdd6669ff90300f7d58d51bf315072f930a4f1bd459d2f9/SQLAlchemy-0.7.1.tar.gz ...
Downloaded /home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz
Direct zipimport failed with Traceback (most recent call last):
  File "<frozen zipimport>", line 92, in __init__
KeyError: '/home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/media/sf_Dropbox/code/justuse/src/use/use.py", line 939, in _use_str
    importer = zipimport.zipimporter(path)
  File "<frozen zipimport>", line 94, in __init__
  File "<frozen zipimport>", line 386, in _read_directory
zipimport.ZipImportError: not a Zip file: '/home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz'
 attempting to extract and load manually...
Extracting to /home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar ...
Extracted.

Problem use()ing plotnine in jupyter

import use
p9 = use("plotnine", version="0.7.1")

results in

/home/thorsten/anaconda3/lib/python3.8/site-packages/palettable/colorbrewer/colorbrewer.py:7: 
UserWarning: Module use was already imported from None, but /media/sf_Dropbox/code/justuse/src is being added to sys.path

Errors about missing packages during pip install

$ uname -a
Linux ip-[redacted] 5.8.0-1038-aws #40~20.04.1-Ubuntu SMP Thu Jun 17 13:25:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ which pip3
/home/ubuntu/.local/bin/pip3

$ pip3 --version
pip 21.1.2 from /home/ubuntu/.local/lib/python3.8/site-packages/pip (python 3.8)

$ which python3
/usr/bin/python3
$ python3 --version
Python 3.8.10

$ pip3 install justuse

Defaulting to user installation because normal site-packages is not writeable
Collecting justuse
  Downloading justuse-0.3.2.tar.gz (15 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_3873643c28504b8a8d18fd52dd7e5026/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_3873643c28504b8a8d18fd52dd7e5026/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-8haaxeso
         cwd: /tmp/pip-install-vo8rj7tg/justuse_3873643c28504b8a8d18fd52dd7e5026/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_3873643c28504b8a8d18fd52dd7e5026/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_3873643c28504b8a8d18fd52dd7e5026/src/use/use.py", line 90, in <module>
        import mmh3
    ModuleNotFoundError: No module named 'mmh3'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/11/17/8fa79203609f9e92ae67e3133099507128c7792ae5ea87e5fb422cc7d71d/justuse-0.3.2.tar.gz#sha256=49f46a67a37a059a96fb015fef981a0226d3fb0ddeff78e9997d88032ed62016 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.3.1.tar.gz (14 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_0039c71f3c7c4f9ebefe48fa7f6420c0/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_0039c71f3c7c4f9ebefe48fa7f6420c0/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-lcjowzhk
         cwd: /tmp/pip-install-vo8rj7tg/justuse_0039c71f3c7c4f9ebefe48fa7f6420c0/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_0039c71f3c7c4f9ebefe48fa7f6420c0/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_0039c71f3c7c4f9ebefe48fa7f6420c0/src/use/use.py", line 85, in <module>
        import mmh3
    ModuleNotFoundError: No module named 'mmh3'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/2f/0c/f6406484a8ad30b64f03f15a5ed2c97b4d3ebb84a3374a3220b428d9a3b9/justuse-0.3.1.tar.gz#sha256=743139ed7cdffc2d015ad9ce32f4765e27d90bbfcab7ed543e622493c5cb8bc8 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.3.0.tar.gz (14 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_319ce5cf6ea54c8e8b1323bb98deb203/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_319ce5cf6ea54c8e8b1323bb98deb203/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-7350g5jt
         cwd: /tmp/pip-install-vo8rj7tg/justuse_319ce5cf6ea54c8e8b1323bb98deb203/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_319ce5cf6ea54c8e8b1323bb98deb203/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_319ce5cf6ea54c8e8b1323bb98deb203/src/use/use.py", line 85, in <module>
        import mmh3
    ModuleNotFoundError: No module named 'mmh3'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/c6/2c/a1c0c4fa17ad8d1bdab659861dcb80f8e0f461020fbefadebafd9a466d47/justuse-0.3.0.tar.gz#sha256=ad8edb9ffc4fc0ebb730001353ee1eff1bda0205223874502b6c5e2072dd873a (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.2.6.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_af643f4ee5164246b57f3135486f8a58/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_af643f4ee5164246b57f3135486f8a58/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-xauobnqo
         cwd: /tmp/pip-install-vo8rj7tg/justuse_af643f4ee5164246b57f3135486f8a58/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_af643f4ee5164246b57f3135486f8a58/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_af643f4ee5164246b57f3135486f8a58/src/use/use.py", line 79, in <module>
        import mmh3
    ModuleNotFoundError: No module named 'mmh3'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/4b/47/c16bd826c3753b043b0f24790256c113e2e9faeec54eedaa75c9a9c11787/justuse-0.2.6.tar.gz#sha256=5ee9423127b63fe17d36fdc03b96596a929fd62c283c0fc54f623e70626c820d (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.2.5.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_cccc8b6366d44894b9aa48661789bc61/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_cccc8b6366d44894b9aa48661789bc61/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-kcz9z71b
         cwd: /tmp/pip-install-vo8rj7tg/justuse_cccc8b6366d44894b9aa48661789bc61/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_cccc8b6366d44894b9aa48661789bc61/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_cccc8b6366d44894b9aa48661789bc61/src/use/use.py", line 78, in <module>
        import mmh3
    ModuleNotFoundError: No module named 'mmh3'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/e4/da/d27dacfc04c3d28392e91e53d33652d4dec2238d52dd4dd6f86d272970f1/justuse-0.2.5.tar.gz#sha256=33ca9512148554a412b32f81e31cdc8cc85eea34f75eff5b23864c95f2eead70 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.2.3.post1.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_9e75ac5d40964366b3444f97fbe40359/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_9e75ac5d40964366b3444f97fbe40359/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-wv00asii
         cwd: /tmp/pip-install-vo8rj7tg/justuse_9e75ac5d40964366b3444f97fbe40359/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_9e75ac5d40964366b3444f97fbe40359/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_9e75ac5d40964366b3444f97fbe40359/src/use/use.py", line 78, in <module>
        import anyio
    ModuleNotFoundError: No module named 'anyio'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/11/2e/3dc979067ec4fe415c2928b6cfe00ca59f7dcdb60b402ffb82ae21ccdbf3/justuse-0.2.3.post1.tar.gz#sha256=a09d4666112ce57a3855005894cbf61e4f3d15e24ab07052b7d968599d13a149 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.2.3.tar.gz (10 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_a493742a6a3c433f9d3b85f5057f3dc5/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_a493742a6a3c433f9d3b85f5057f3dc5/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-w07cw33q
         cwd: /tmp/pip-install-vo8rj7tg/justuse_a493742a6a3c433f9d3b85f5057f3dc5/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_a493742a6a3c433f9d3b85f5057f3dc5/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_a493742a6a3c433f9d3b85f5057f3dc5/src/use/use.py", line 78, in <module>
        import anyio
    ModuleNotFoundError: No module named 'anyio'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/a3/cc/e4dc199e9e1e2275b885c2b1edf497c3992a012fa42eceb78e009122454e/justuse-0.2.3.tar.gz#sha256=f30566e8121fb2c581b8fefb38d20946170afe462ae98a131e100fdc38b8c112 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.2.2.tar.gz (10.0 kB)
    ERROR: Command errored out with exit status 1:
     command: /usr/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-vo8rj7tg/justuse_20e54f71fb1446cbb0f1250c6e6289f3/setup.py'"'"'; __file__='"'"'/tmp/pip-install-vo8rj7tg/justuse_20e54f71fb1446cbb0f1250c6e6289f3/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-z2jqkm57
         cwd: /tmp/pip-install-vo8rj7tg/justuse_20e54f71fb1446cbb0f1250c6e6289f3/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_20e54f71fb1446cbb0f1250c6e6289f3/setup.py", line 14, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_20e54f71fb1446cbb0f1250c6e6289f3/src/use/use.py", line 78, in <module>
        import anyio
    ModuleNotFoundError: No module named 'anyio'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/07/8c/e921874af043546e5facae0974388b5ea676c6754b913b493e4e7f737bc9/justuse-0.2.2.tar.gz#sha256=1b74f2c43bb0b39d46dafb1599bc895fb87b3bee809614e8b104d80d4e429f31 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check          cwd: /tmp/pip-install-vo8rj7tg/justuse_2865f4d7a1394852846722f62086beef/
    Complete output (7 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-vo8rj7tg/justuse_2865f4d7a1394852846722f62086beef/setup.py", line 12, in <module>
        import use
      File "/tmp/pip-install-vo8rj7tg/justuse_2865f4d7a1394852846722f62086beef/src/use/use.py", line 78, in <module>
        import anyio
    ModuleNotFoundError: No module named 'anyio'
    ----------------------------------------
WARNING: Discarding https://files.pythonhosted.org/packages/96/d9/df8955a0df7e44327ea3d26d113107e8e8759ba6b9203ffd300152b07eae/justuse-0.2.0.tar.gz#sha256=b2a8a89a487c870fb34e422baab08690cab3c866bbbb08ec6bbaf0cb2b31d8f8 (from https://pypi.org/simple/justuse/) (requires-python:>=3.8). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  Downloading justuse-0.1.0.post5.tar.gz (7.7 kB)
Collecting anyio>=3.1.0
  Downloading anyio-3.2.1-py3-none-any.whl (75 kB)
     |โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 75 kB 5.9 MB/s
Collecting mmh3>=2.2.0
  Downloading mmh3-3.0.0-cp38-cp38-manylinux2010_x86_64.whl (50 kB)
     |โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 50 kB 9.7 MB/s
Collecting requests>=2.24.0
  Downloading requests-2.25.1-py2.py3-none-any.whl (61 kB)
     |โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ| 61 kB 9.6 MB/s
Requirement already satisfied: yarl>=1.6.3 in ./.local/lib/python3.8/site-packages (from justuse) (1.6.3)
Requirement already satisfied: idna>=2.8 in /usr/lib/python3/dist-packages (from anyio>=3.1.0->justuse) (2.8)
Collecting sniffio>=1.1
  Downloading sniffio-1.2.0-py3-none-any.whl (10 kB)
Requirement already satisfied: chardet<5,>=3.0.2 in /usr/lib/python3/dist-packages (from requests>=2.24.0->justuse) (3.0.4)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/lib/python3/dist-packages (from requests>=2.24.0->justuse) (1.25.8)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python3/dist-packages (from requests>=2.24.0->justuse) (2019.11.28)
Requirement already satisfied: multidict>=4.0 in ./.local/lib/python3.8/site-packages (from yarl>=1.6.3->justuse) (5.1.0)
Building wheels for collected packages: justuse
  Building wheel for justuse (setup.py) ... done
  Created wheel for justuse: filename=justuse-0.1.0.post5-py3-none-any.whl size=7800 sha256=c9a0ea33000815077c218b0cd430b29123cf548574c73c03732c7d9209585f4f
  Stored in directory: /home/ubuntu/.cache/pip/wheels/f5/f8/8c/54a9fe67d21a3d3baf69e8a809e96e02310b52b9360a3a2304
Successfully built justuse
Installing collected packages: sniffio, requests, mmh3, anyio, justuse
Successfully installed anyio-3.2.1 justuse-0.1.0.post5 mmh3-3.0.0 requests-2.25.1 sniffio-1.2.0
WARNING: You are using pip version 21.1.2; however, version 21.1.3 is available.
You should consider upgrading via the '/usr/bin/python3 -m pip install --upgrade pip' command.

dataclasses don't like use(Path())

hama = use(
    Path("/media/sf_Dropbox/mcs/Code/Arrhythmia_detection/hamamea/hama.py"),
)

with

from dataclasses import dataclass
@dataclass(init=False, repr=False)
class Stats:
    data_length: int  # total length of data
    peak_count = int  # number of detected peaks,

causes

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-6-31ead0ea4bf8> in <module>
----> 1 hama = use(
      2     Path("/media/sf_Dropbox/mcs/Code/Arrhythmia_detection/hamamea/hama.py"),
      3 )

/media/sf_Dropbox/code/use/src/use/use.py in wrapper(*args, **kw)
    135     dispatcher = singledispatch(func)
    136     def wrapper(*args, **kw):
--> 137         return dispatcher.dispatch(args[1].__class__)(*args, **kw)
    138     wrapper.register = dispatcher.register
    139     update_wrapper(wrapper, func)

/media/sf_Dropbox/code/use/src/use/use.py in _use_path(self, path, reloading, initial_globals)
    256             else:
    257                 with open(path, "rb") as file:
--> 258                     mod = build_mod(name, file.read(), initial_globals)
    259             self.__using[name] = mod, spec, inspect.getframeinfo(inspect.currentframe())
    260             return mod

/media/sf_Dropbox/code/use/src/use/use.py in build_mod(name, code, initial_globals)
    143     mod = ModuleType(name)
    144     mod.__dict__.update(initial_globals or {})
--> 145     exec(compile(code, name, "exec"), mod.__dict__)
    146     return mod
    147 

hama in <module>

~/anaconda3/lib/python3.8/dataclasses.py in wrap(cls)
   1009 
   1010     def wrap(cls):
-> 1011         return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
   1012 
   1013     # See if we're being called as @dataclass or @dataclass().

~/anaconda3/lib/python3.8/dataclasses.py in _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
    859     # things, and set the default values (as class attributes) where
    860     # we can.
--> 861     cls_fields = [_get_field(cls, name, type)
    862                   for name, type in cls_annotations.items()]
    863     for f in cls_fields:

~/anaconda3/lib/python3.8/dataclasses.py in <listcomp>(.0)
    859     # things, and set the default values (as class attributes) where
    860     # we can.
--> 861     cls_fields = [_get_field(cls, name, type)
    862                   for name, type in cls_annotations.items()]
    863     for f in cls_fields:

~/anaconda3/lib/python3.8/dataclasses.py in _get_field(cls, a_name, a_type)
    710         if (_is_classvar(a_type, typing)
    711             or (isinstance(f.type, str)
--> 712                 and _is_type(f.type, cls, typing, typing.ClassVar,
    713                              _is_classvar))):
    714             f._field_type = _FIELD_CLASSVAR

~/anaconda3/lib/python3.8/dataclasses.py in _is_type(annotation, cls, a_module, a_type, is_type_predicate)
    656             # No module name, assume the class's module did
    657             # "from dataclasses import InitVar".
--> 658             ns = sys.modules.get(cls.__module__).__dict__
    659         else:
    660             # Look up module_name in the class's module.

AttributeError: 'NoneType' object has no attribute '__dict__'

it should be possible to optionally auto-install packages

use() should take an "auto_install" argument in conjunction with a specified version. Version-pinning is much more picky than the package-management approach of "greater/smaller than" version-specifiers. While pinning solves any incompatibility issues that come with API changes (and even upstream corruption), it might involve a lot more manual work with installing and managing virtual envs.
For the usecases that use() is designed to solve - fiddly, non-production code that is imported from anywhere but a locally, well groomed package, trying to maintain best-practices with a virtual env and installing everything manually is quite a hassle.
There is also no way for an external package manager to maintain those packages automatically because there usually is no additional metadata to go on other than the code-module itself.
Also, if you use(some local file or external URL), there is nothing to go on for classical package managers, so the installation must either be done by the user before running the code, making educated guess about what to install - if the used() code also uses() their external dependencies however, this can be done automatically, efficiently and safely.

make use install()able - globally add to builtins

from the icecream docs:

To make ic() available in every file without needing to be imported in every file, you can install() it.

install() adds ic() to the builtins module, which is shared amongst all files imported by the interpreter. Similarly, ic() can later be uninstall()ed, too.

use should have that too :)

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.

A new use() case for iterators

The internal dependency graph could output an iterator of arguments for use() that could simplify testing and reproducability of data science code.

use("sqlalchemy", version="0.7.1", hashes={"5ef95d19c31a8cd3905c697be0a7e94e70ab1926ecd4159c3e6c1cf01fc3c492"}, modes=use.auto_install) fails to shadow a local install

sql = use("sqlalchemy", version="0.7.1", hash_value="5ef95d19c31a8cd3905c697be0a7e94e70ab1926ecd4159c3e6c1cf01fc3c492", auto_install=True)

Last executed at 2021-07-05 15:50:28 in 3.49s

Downloading https://files.pythonhosted.org/packages/aa/63/5ddf80758f953fdd6669ff90300f7d58d51bf315072f930a4f1bd459d2f9/SQLAlchemy-0.7.1.tar.gz ...
Downloaded /home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz
Direct zipimport failed with Traceback (most recent call last):
File "", line 92, in init
KeyError: '/home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/media/sf_Dropbox/code/justuse/src/use/use.py", line 939, in _use_str
importer = zipimport.zipimporter(path)
File "", line 94, in init
File "", line 386, in _read_directory
zipimport.ZipImportError: not a Zip file: '/home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar.gz'
attempting to extract and load manually...
Extracting to /home/thorsten/.justuse-python/packages/SQLAlchemy-0.7.1.tar ...
Extracted.

sql.version

'1.3.20'

numba.jit doesn't work with aspectize

test = use(use.Path("../tests/.test1.py"), aspectize={(use.aspect.FUNCTION, ".*"):numba.jit})

with .test1.py:

def foo(x):
   return x*2

fails with:

<.test1>:1: NumbaWarning: 
Compilation is falling back to object mode WITH looplifting enabled because Function foo failed at nopython mode lowering due to: can't compile foo: import of module .test1 failed
  def foo(x):

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/.local/lib/python3.9/site-packages/numba/core/environment.py in from_fndesc(cls, fndesc)
     20             # Avoid creating new Env
---> 21             return cls._memo[fndesc.env_name]
     22         except KeyError:

/usr/lib/python3.9/weakref.py in __getitem__(self, key)
    133             self._commit_removals()
--> 134         o = self.data[key]()
    135         if o is None:

KeyError: '_ZN08NumbaEnv05test17foo$241E8pyobject'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
~/.local/lib/python3.9/site-packages/numba/core/funcdesc.py in lookup_module(self)
     92             try:
---> 93                 return sys.modules[self.modname]
     94             except:

KeyError: '.test1'

During handling of the above exception, another exception occurred:

ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-17-b1fb48be0463> in <module>
----> 1 test.foo(4)

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
    437                     e.patch_message('\n'.join((str(e).rstrip(), help_msg)))
    438             # ignore the FULL_TRACEBACKS config, this needs reporting!
--> 439             raise e
    440         finally:
    441             self._types_active_call = []

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in _compile_for_args(self, *args, **kws)
    370         return_val = None
    371         try:
--> 372             return_val = self.compile(tuple(argtypes))
    373         except errors.ForceLiteralArg as e:
    374             # Received request for compiler re-entry with the list of arguments

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in compile(self, sig)
    907                 with ev.trigger_event("numba:compile", data=ev_details):
    908                     try:
--> 909                         cres = self._compiler.compile(args, return_type)
    910                     except errors.ForceLiteralArg as e:
    911                         def folded(args, kws):

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in compile(self, args, return_type)
     77 
     78     def compile(self, args, return_type):
---> 79         status, retval = self._compile_cached(args, return_type)
     80         if status:
     81             return retval

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in _compile_cached(self, args, return_type)
     91 
     92         try:
---> 93             retval = self._compile_core(args, return_type)
     94         except errors.TypingError as e:
     95             self._failed_cache[key] = e

~/.local/lib/python3.9/site-packages/numba/core/dispatcher.py in _compile_core(self, args, return_type)
    104 
    105         impl = self._get_implementation(args, {})
--> 106         cres = compiler.compile_extra(self.targetdescr.typing_context,
    107                                       self.targetdescr.target_context,
    108                                       impl,

~/.local/lib/python3.9/site-packages/numba/core/compiler.py in compile_extra(typingctx, targetctx, func, args, return_type, flags, locals, library, pipeline_class)
    604     pipeline = pipeline_class(typingctx, targetctx, library,
    605                               args, return_type, flags, locals)
--> 606     return pipeline.compile_extra(func)
    607 
    608 

~/.local/lib/python3.9/site-packages/numba/core/compiler.py in compile_extra(self, func)
    351         self.state.lifted = ()
    352         self.state.lifted_from = None
--> 353         return self._compile_bytecode()
    354 
    355     def compile_ir(self, func_ir, lifted=(), lifted_from=None):

~/.local/lib/python3.9/site-packages/numba/core/compiler.py in _compile_bytecode(self)
    413         """
    414         assert self.state.func_ir is None
--> 415         return self._compile_core()
    416 
    417     def _compile_ir(self):

~/.local/lib/python3.9/site-packages/numba/core/compiler.py in _compile_core(self)
    393                 self.state.status.fail_reason = e
    394                 if is_final_pipeline:
--> 395                     raise e
    396         else:
    397             raise CompilerError("All available pipelines exhausted")

~/.local/lib/python3.9/site-packages/numba/core/compiler.py in _compile_core(self)
    384             res = None
    385             try:
--> 386                 pm.run(self.state)
    387                 if self.state.cr is not None:
    388                     break

~/.local/lib/python3.9/site-packages/numba/core/compiler_machinery.py in run(self, state)
    337                     (self.pipeline_name, pass_desc)
    338                 patched_exception = self._patch_error(msg, e)
--> 339                 raise patched_exception
    340 
    341     def dependency_analysis(self):

~/.local/lib/python3.9/site-packages/numba/core/compiler_machinery.py in run(self, state)
    328                 pass_inst = _pass_registry.get(pss).pass_inst
    329                 if isinstance(pass_inst, CompilerPass):
--> 330                     self._runPass(idx, pass_inst, state)
    331                 else:
    332                     raise BaseException("Legacy pass in use")

~/.local/lib/python3.9/site-packages/numba/core/compiler_lock.py in _acquire_compile_lock(*args, **kwargs)
     33         def _acquire_compile_lock(*args, **kwargs):
     34             with self:
---> 35                 return func(*args, **kwargs)
     36         return _acquire_compile_lock
     37 

~/.local/lib/python3.9/site-packages/numba/core/compiler_machinery.py in _runPass(self, index, pss, internal_state)
    287             mutated |= check(pss.run_initialization, internal_state)
    288         with SimpleTimer() as pass_time:
--> 289             mutated |= check(pss.run_pass, internal_state)
    290         with SimpleTimer() as finalize_time:
    291             mutated |= check(pss.run_finalizer, internal_state)

~/.local/lib/python3.9/site-packages/numba/core/compiler_machinery.py in check(func, compiler_state)
    260 
    261         def check(func, compiler_state):
--> 262             mangled = func(compiler_state)
    263             if mangled not in (True, False):
    264                 msg = ("CompilerPass implementations should return True/False. "

~/.local/lib/python3.9/site-packages/numba/core/object_mode_passes.py in run_pass(self, state)
    118                                            state.flags)
    119 
--> 120         lowered = backend_object_mode()
    121         signature = typing.signature(state.return_type, *state.args)
    122         from numba.core.compiler import compile_result

~/.local/lib/python3.9/site-packages/numba/core/object_mode_passes.py in backend_object_mode()
    113                               (state.nargs - len(state.args)))
    114 
--> 115             return self._py_lowering_stage(state.targetctx,
    116                                            state.library,
    117                                            state.func_ir,

~/.local/lib/python3.9/site-packages/numba/core/object_mode_passes.py in _py_lowering_stage(self, targetctx, library, interp, flags)
     75         )
     76         with targetctx.push_code_library(library):
---> 77             lower = pylowering.PyLower(targetctx, library, fndesc, interp)
     78             lower.lower()
     79             if not flags.no_cpython_wrapper:

~/.local/lib/python3.9/site-packages/numba/core/lowering.py in __init__(self, context, library, fndesc, func_ir, metadata)
     35         # Python execution environment (will be available to the compiled
     36         # function).
---> 37         self.env = Environment.from_fndesc(self.fndesc)
     38 
     39         # Internal states

~/.local/lib/python3.9/site-packages/numba/core/environment.py in from_fndesc(cls, fndesc)
     21             return cls._memo[fndesc.env_name]
     22         except KeyError:
---> 23             inst = cls(fndesc.lookup_globals())
     24             inst.env_name = fndesc.env_name
     25             cls._memo[fndesc.env_name] = inst

~/.local/lib/python3.9/site-packages/numba/core/funcdesc.py in lookup_globals(self)
     79         dynamically (i.e. exec)
     80         """
---> 81         return self.global_dict or self.lookup_module().__dict__
     82 
     83     def lookup_module(self):

~/.local/lib/python3.9/site-packages/numba/core/funcdesc.py in lookup_module(self)
     93                 return sys.modules[self.modname]
     94             except:
---> 95                 raise ModuleNotFoundError(
     96                     f"can't compile {self.qualname}: "
     97                     f"import of module {self.modname} failed")

ModuleNotFoundError: can't compile foo: import of module .test1 failed

use(str, auto_install=..) picks the wrong arch for download

LUbuntu VM, Jupyter with Python '3.8.5 (default, Sep 4 2020, 07:30:14) \n[GCC 7.3.0]'

np = use("numpy", version="1.21.0rc2", hash_value="3c90b0bb77615bda5e007cfa4c53eb6097ecc82e247726e0eb138fcda769b45d", auto_install=True)

Last executed at 2021-07-08 19:05:45 in 25.14s

Downloading https://files.pythonhosted.org/packages/02/d2/2d0289221871ef940f9ff72b0a2576ac6b2efda77e0a01d5f314190b502b/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl ...
Downloaded /home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl
Direct zipimport failed with Traceback (most recent call last):
  File "/home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl/numpy/core/__init__.py", line 22, in <module>
    from . import multiarray
  File "<frozen zipimport>", line 259, in load_module
  File "/home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl/numpy/core/multiarray.py", line 12, in <module>
    from . import overrides
  File "<frozen zipimport>", line 259, in load_module
  File "/home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl/numpy/core/overrides.py", line 7, in <module>
    from numpy.core._multiarray_umath import (
ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/media/sf_Dropbox/code/justuse/src/use/use.py", line 975, in _use_str
    mod = importer.load_module(module_name)
  File "<frozen zipimport>", line 259, in load_module
  File "/home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl/numpy/__init__.py", line 150, in <module>
    from . import core
  File "<frozen zipimport>", line 259, in load_module
  File "/home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64.whl/numpy/core/__init__.py", line 48, in <module>
    raise ImportError(msg)
ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.8 from "/home/thorsten/anaconda3/bin/python"
  * The NumPy version is: "1.21.0rc2"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: No module named 'numpy.core._multiarray_umath'

 attempting to extract and load manually...
Extracting to /home/thorsten/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64 ...
Extracted.

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
~/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64/numpy/core/__init__.py in <module>
     21 try:
---> 22     from . import multiarray
     23 except ImportError as exc:

~/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64/numpy/core/multiarray.py in <module>
     11 
---> 12 from . import overrides
     13 from . import _multiarray_umath

~/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64/numpy/core/overrides.py in <module>
      6 
----> 7 from numpy.core._multiarray_umath import (
      8     add_docstring, implement_array_function, _get_implementing_args)

ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'

During handling of the above exception, another exception occurred:

ImportError                               Traceback (most recent call last)
<ipython-input-3-7b5b829ff05b> in <module>
----> 1 np = use("numpy", version="1.21.0rc2", hash_value="3c90b0bb77615bda5e007cfa4c53eb6097ecc82e247726e0eb138fcda769b45d", auto_install=True)

/media/sf_Dropbox/code/justuse/src/use/use.py in wrapper(*args, **kw)
    148     dispatcher = singledispatch(func)
    149     def wrapper(*args, **kw):
--> 150         return dispatcher.dispatch(args[1].__class__)(*args, **kw)
    151     wrapper.register = dispatcher.register
    152     update_wrapper(wrapper, func)

/media/sf_Dropbox/code/justuse/src/use/use.py in _use_str(self, name, version, initial_globals, auto_install, hash_algo, hash_value, default, aspectize, path_to_url, import_to_use)
   1040                 original_cwd = Path.cwd()
   1041                 os.chdir(folder)
-> 1042                 mod = importlib.import_module(module_name)
   1043                 for key in ("__name__", "__package__", "__path__", "__file__", "__version__", "__author__"):
   1044                     if not hasattr(mod, key): continue

~/anaconda3/lib/python3.8/importlib/__init__.py in import_module(name, package)
    125                 break
    126             level += 1
--> 127     return _bootstrap._gcd_import(name[level:], package, level)
    128 
    129 

~/anaconda3/lib/python3.8/importlib/_bootstrap.py in _gcd_import(name, package, level)

~/anaconda3/lib/python3.8/importlib/_bootstrap.py in _find_and_load(name, import_)

~/anaconda3/lib/python3.8/importlib/_bootstrap.py in _find_and_load_unlocked(name, import_)

~/anaconda3/lib/python3.8/importlib/_bootstrap.py in _load_unlocked(spec)

~/anaconda3/lib/python3.8/importlib/_bootstrap_external.py in exec_module(self, module)

~/anaconda3/lib/python3.8/importlib/_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)

~/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64/numpy/__init__.py in <module>
    148     from . import _distributor_init
    149 
--> 150     from . import core
    151     from .core import *
    152     from . import compat

~/.justuse-python/packages/numpy-1.21.0rc2-cp38-cp38-win_amd64/numpy/core/__init__.py in <module>
     46 """ % (sys.version_info[0], sys.version_info[1], sys.executable,
     47         __version__, exc)
---> 48     raise ImportError(msg)
     49 finally:
     50     for envkey in env_added:

ImportError: 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.8 from "/home/thorsten/anaconda3/bin/python"
  * The NumPy version is: "1.21.0rc2"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: No module named 'numpy.core._multiarray_umath'

ic won't work in jupyter

p9 = use("plotnine", version="0.7.1")
ic| Error: Failed to access the underlying source code for analysis. Was ic() invoked in an interpreter (e.g. python -i), a frozen application (e.g. packaged with PyInstaller), or did the underlying source code change during execution?

there should be a way to track down use() dependencies - internal dependency tree

use.dependencies could be an internal class representing all imports and use()s with the line within the source where they happen and as a recursive structure, keeping track of the order in which things are imported/use()d. use.dependencies could implement the iterator protocol for linearisation of the recursive structure in order to be use()d via the iterator (#27) case for testing and reproduction of complex, distributed code, as well as easy documentation.

Classical imports could also be represented as their use() equivalent, making transition to justuse easier.

There also could be a use.dependencies.plot() which could take advantage of networkx or some other graph-plotting library for visualization of the whole graph.

use(Path(..)) with a relative Path can't find module in same folder if not in working directory

within a jupyter notebook started on my VM desktop,

mea = use(
    Path("/media/sf_Dropbox/mcs/Code/Arrhythmia_detection/hamamea/mea.py"),
    reloading=True,
)

and use(use.Path("test.py"), initial_globals=globals()) within that file (test.py exists in the same folder),
I get a ModuleNotFoundError.
For relative paths, the parent directory of the executing file needs to be applied, not the working directory.

It should be possible to pass in an argument "import_to_use" which maps all calls to import to the corresponding use()

Auto-installed packages with different versions might also require dependencies with different versions, but the original author couldn't anticipate that an "import X" couldn't be resolved to the expected version due to the limitations of import and correspondingly, pip.
Now, if two packages with different versions and subsequently, requiring dependencies with different versions, are installed, one of the two packages (the older one, most likely) must fail. An explicit and simple way to resolve this issue would be to have an import_to_use argument like: use("package", import_to_use={"foo": {"foo", version:"1.2.3", hash_value:"98dfj9898df", auto_install:True}) which would be passed down to all use()s in that package (if there are any) and set up a patch for imports in those modules that traps any attempt at trying to "import package" to be reformulated as a call to use() with the given arguments.

If use()-ing a module which imports something that can't be found, the trace doesn't propagate properly

ModuleNotFoundError Traceback (most recent call last)
in
----> 1 modA = use(use.Path("../tests/modA.py"))

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in wrapper(*args, **kw)
123 dispatcher = singledispatch(func)
124 def wrapper(*args, **kw):
--> 125 return dispatcher.dispatch(args[1].class)(*args, **kw)
126 wrapper.register = dispatcher.register
127 update_wrapper(wrapper, func)

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in _use_path(self, path, reloading, initial_globals)
267 # CODE AFTER THIS APPEARS NOT TO EXIST - WTF?!
268 self.__using[name] = path.resolve()
--> 269 mod = build_mod(name, file.read(), initial_globals)
270 return mod
271

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in build_mod(name, code, initial_globals)
144 )
145 # BEWARE WTF: CODE AFTER THIS APPEAR NOT TO EXIST - IT DOES NOT RETURN!
--> 146 exec(compile(code, name, "exec"), mod.dict)
147 #return mod
148

in

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in wrapper(*args, **kw)
123 dispatcher = singledispatch(func)
124 def wrapper(*args, **kw):
--> 125 return dispatcher.dispatch(args[1].class)(*args, **kw)
126 wrapper.register = dispatcher.register
127 update_wrapper(wrapper, func)

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in _use_path(self, path, reloading, initial_globals)
267 # CODE AFTER THIS APPEARS NOT TO EXIST - WTF?!
268 self.__using[name] = path.resolve()
--> 269 mod = build_mod(name, file.read(), initial_globals)
270 return mod
271

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in build_mod(name, code, initial_globals)
144 )
145 # BEWARE WTF: CODE AFTER THIS APPEAR NOT TO EXIST - IT DOES NOT RETURN!
--> 146 exec(compile(code, name, "exec"), mod.dict)
147 #return mod
148

in

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in wrapper(*args, **kw)
123 dispatcher = singledispatch(func)
124 def wrapper(*args, **kw):
--> 125 return dispatcher.dispatch(args[1].class)(*args, **kw)
126 wrapper.register = dispatcher.register
127 update_wrapper(wrapper, func)

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in _use_path(self, path, reloading, initial_globals)
267 # CODE AFTER THIS APPEARS NOT TO EXIST - WTF?!
268 self.__using[name] = path.resolve()
--> 269 mod = build_mod(name, file.read(), initial_globals)
270 return mod
271

/media/sf_Dropbox_(Privat)/code/justuse/src/use/use.py in build_mod(name, code, initial_globals)
144 )
145 # BEWARE WTF: CODE AFTER THIS APPEAR NOT TO EXIST - IT DOES NOT RETURN!
--> 146 exec(compile(code, name, "exec"), mod.dict)
147 #return mod
148

in

ModuleNotFoundError: No module named 'foo'

Version upgrade warning like pip?

WARNING: You are using pip version 21.1.2; however, version 21.1.3 is available.
You should consider upgrading via the 'C:\Users\micro\AppData\Local\Programs\Python\Python39\python.exe -m pip install --upgrade pip' command.

We similarly could check for the newest version in Use.__init__ and warn the user whenever a new version is available, although we'll need a new class of Warning so users can filter it and/or we could add a config setting to disable the warning.

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.