Add GitHub Support

Add GitHubService which implements IService protocol and implement it's functions. You can use GitHub Checks API.

Hello! I'm interested in working on this issue 🙂

Hi! Great 👍 If you have any questions feel free to contact me 🙂

Hi @Jakub-Vacek! Since the Checks API seems to only allow getting a single check run given an id. Will the update to the UI for the user to input the check_run_id b supposed to be done in #6 or will this be the projectId? Or should I be looking elsewhere to display several pipelines?


Knora Documentation > Publishing and Deployment

Fix make targets docker-build and docker-publish
Fix Dockerhub Organization name and link.

Thanks for the fixes.

@benjamingeer here we have the same problem, as in the other PR. Github-CI is not running for PRs coming from outside of our organization.

@benjamingeer […] Github-CI is not running for PRs coming from outside of our organization

Just found this thread in the GitHub Support Community linking to Chris Patterson's  blog post "GitHub Actions improvements for fork and pull request workflows " (August 3, 2020).

Thanks for the link.

@subotic Do you know if there's some way we can merge this and #1688?

@benjamingeer We could allow admins to merge despite the tests not running. In this case, this should be ok.


Aspectize should be more user-friendly with decorating methods

Yay for this! As a terse and insufficient follow-up to beartype/beartype#73, I was thinking of maybe a decorator-via-aspectization justuse API resembling:
from beartype import beartype
from justuse import use

# A "muh_package" proxy transitively decorating all callables
# whose fully-qualified names match "muh_package.*" with
# the @beartype decorator. It feels good, man.
muh_package_beartyped = use(
    'muh_package',
    aspectize_package_callables_with_decorator=beartype,  # <-- heh
)

As parameter names go, aspectize_package_callables_with_decorator is longer than Satan's grubby beard. That's bad. But that's the name we're going with! You previously mentioned pattern matching via an arbitrary boolean tester (e.g., inspect.isfunction()), which suggests you have more general-purpose ideas in mind. That's good.
Let's general-purpose that API up.  May we all survive the brewing pandemic hellstorm and live to tell the tale over thick and pungent tiergarten lager.

Oh. You already invented something substantially smarter by overloading the matrix multiplication operator on proxied modules to aspectize supplied decorators across those modules:
import use
from beartype import beartype
from use import isfunction

np = use('numpy')
np @ (isfunction, '', beartype)

Welp... that's a micdrop. :microphone:

Hehe.. well, I wished it was all that simple. At the moment we just recycle inspect.isfunction, thus only catch pure functions and only go through the first level with no recursion (thus methods already can't work).
To make this work with beartype we need:

make a check that catches everything beartype can be applied to
recursively apply the decorator throughout the object hierarchy (probably closures will need extra attention)
have a kind of dict of set and deque to prevent applying decorators recursively in a loop and be able to undecorate on the fly (just because we can)

@leycec the broadest and most naive check function for beartype I guess would be
def beartypeable(obj):
    try:
        beartype(obj)
        return True
    except:
        return False

maybe we can narrow it down a bit and make it also applicable to users who don't use beartype (boo!) ;-)
Any suggestions?

Right. Classic Easier to Ask for forgiveness than Permission (EAFP) design pattern up in here.
As usual, that definitely works – but compromises performance in a probably measurable way, because exception handling is as slow as @leycec doing a double face-palm in front of a double rainbow live on Twitch. Technically, exception handling is fast unless an exception is actually raised. Sadly, that's sorta the same thing in this case, because classes are everywhere and @beartype currently raises exceptions on classes. </gulp>
Given that, isinstance()-based detection would service everyone's need for speed while still working. For his and her maintainability, we go the extra mile and depend purely on builtins to do it. Hu-ah!
In my sleep-deprived mind's eye, I am envisioning something devious like:
from types import FunctionType

def is_callable_nontype(obj):
    '''
    ``True`` only if the passed object is a **pure-Python callable non-type**
    (i.e., function or method defined in Python).
    '''
    return isinstance(obj, FunctionType)

# This alias is currently true. Beartype will decorate classes too at some
# future date that shall be heralded for all time, however. At that time,
# this alias will probably need to be replaced with something resembling:
#     def is_beartypeable(obj):
#         return isinstance(obj, (FunctionType, type))
is_beartypeable = is_callable_nontype

:exploding_head:

After realizing that object.getattribute is the only reliable source of truth regarding attribute discovery, I was able to simplify the aspectizing code quite a bit and make deep recursion work. Check it out :) https://github.com/amogorkon/justuse/blob/5328e253819aa5f3aed86f14aa41a17e5216bb63/src/use/aspectizing.py#L28
And I also learned that everything that indeed IS callable MUST have a (albeit often hidden) .__call__ method.
def f(): pass

class A: pass

a = A()

print(object.__getattribute__(f, "__call__"))
print(object.__getattribute__(A, "__call__"))
print(object.__getattribute__(a, "__call__"))

----
<method-wrapper '__call__' of function object at 0x000001B31733FCA0>
<method-wrapper '__call__' of type object at 0x000001B31900E0D0>
Traceback (most recent call last):
  File "F:\Dropbox (Privat)\code\justuse\tests\.tests\.test3.py", line 9, in <module>
    print(object.__getattribute__(a, "__call__"))
AttributeError: 'A' object has no attribute '__call__'

Also, there's one small issue with closures
def f():
   def g():
       print("foo")

>>> f.g
Traceback (most recent call last):
  File "<pyshell>", line 1, in <module>
AttributeError: 'function' object has no attribute 'g'

g doesn't exist outside of calling f, so there's no way to decorate with our "classic" approach.
We need to manipulate the code of f on either the AST or bytecode level to get there.

What about properties? methods? classes that act like functions either by __init__ or __call__ .. and now we're wrestling with Enum members that have some __func__ causing recursion like use.Modes.auto_install.fastfail.no_public_installation.auto_install.fastfail .. AHHHH... going crazy

inspired by my question on discord #esoteric-python a possible POC for decorating closures:
( https://gist.github.com/thatbirdguythatuknownot/524234dbe8415f1873da57713fa0869c )
import types
import opcode
MAKE_FUNCTION = opcode.opmap['MAKE_FUNCTION']
del opcode

def decorate_inner(decorator, name):
    def actual_decorator(outer_fn):
        # Try and find the decorator function in co_consts,
        # perform EAFP
        co_consts = outer_fn.__code__.co_consts
        try:
            index = co_consts.index(decorator)
        except ValueError:
            index = len(co_consts)
            outer_fn.__code__ = outer_fn.__code__.replace(
                co_consts=co_consts + (decorator,)
            )

        # Try and find the name in co_consts,
        # perform EAFP
        try:
            index2 = co_consts.index(
                f"{outer_fn.__code__.co_name}.<locals>.{name}"
            )
        except ValueError:
            raise RuntimeError(f"couldn't find name {name}") from None

        if index2 > 127:
            raise IndexError(f"name index in co_consts is > 127")

        co_code = outer_fn.__code__.co_code
        character = chr(index2)
        base = co_code.find(f'd{character}'.encode())

        while co_code[base+2] is not MAKE_FUNCTION:
            base = co_code.find(f'd{character}'.encode(), base+2)

        outer_fn.__code__ = outer_fn.__code__.replace(
            co_code=(co_code[:base+4]
                    + f'd{chr(index)}\x02\x00\x83\x01'.encode('l1')
                    + co_code[base+4:])
        )
        return outer_fn
    return actual_decorator

def deco(fn):
    def wrapper(*args, **kwargs):
        print("Calling", fn.__name__)
        ret = fn()
        print("Called", fn.__name__)
        return ret

    return wrapper

@decorate_inner(deco, "g")
def f():
    def g():
        return 42
    return g

g = f()
print(g())

OMFG. You've gone into the Dark Zone – that dimly lit crawlspace of Python that only fearless heroes equipped only with a hand-cranked Guido-brand LED headlight dare to tread. I actually didn't know most of the esoteric plumbling you just uncovered like that one-to-one relation between callables and objects with __call__() dunder methods, so this is equally deeply frightening educating for me. That said...
I honestly feel kinda bad. I think we all glibly assumed aspectization was gonna be easy, right? It's a solved problem. Then real-world edge cases like recursive Enum nastiness and deeply nested callables rear their unwashed purulent scalps. Suddenly, it's all gone grimdark. I'm now genuinely concerned about consuming your precious sanity, volunteer enthusiasm, and free time with an increasingly dicey proposition that may not even be fully decidable or solvable in the general case.
Decorators: Feels Bad Even under the Best Case Scenario
Deeply nested callables only magnify that diceyness.
Before going full tilt on a low-level co_const approach that looks scary and smells bad, I'd probably first have a go at decorator unwrapping. The core insight here is that all sane decorators (which means all decorators anyone should care about) return wrapper callables (i.e., functions decorated by the standard @functools.wrap decorator). Each wrapper callable slyly masquerades as its wrappee callable (i.e., the user-defined callable decorated by that wrapper) by propagating critical metadata like the callable name, docstring, and annotations dictionary from that wrappee onto itself.
Usefully, the @functools.wrap decorator preserves access to the wrappee via the __wrapped__ dunder attribute defined on the wrapper. Since callables are often decorated by multiple decorators, retrieving the original undecorated wrappee callable from a stack of deeply nested wrappers is trivial if and only if all of those wrappers are themselves decorated by the standard @functools.wrap decorator.
Of course, this still doesn't necessarily address non-decorator closures or non-closure nested callables. But both of those kinda seem beyond the mandate of sane aspectization. I'd be especially wary of hard-coding unsafe assumptions about code objects into the steaming guts of justuse. CPython version updates often alter code objects internals, published dunder attributes, and use patterns. Too much bleak wizardry and unsafe assumptions about code objects could make justuse more brittle and fragile than it would otherwise be.
A bit of that sort of bleak wizardry is both inevitable and acceptable, of course. For efficiency, @beartype itself now prefers to directly introspect code objects rather than defer to the stable but really slow inspect API. Still, we'd have preferred not to do that. We'll have to maintain that in perpetuity against the perennially moving target that is CPython. :dart:
Woe is us who tread in dark waters.

Nah, don't feel bad. We've been in much worse situations with justuse, this is actually fun - making visible progress every day. We solved the deep recursion mostly, only Enums seem to defy all logic thus far - but we will bent it to our will in time!
We also found a paper on comparing different AOP frameworks for python, so we have some inspiration for the tricky parts.
We're in a perfect position for decorating modules, directly at the source, so we'd be foolish to not embrace this opportunity, even if it means to sell small parts of our souls to call on demonic forces..
Decorating closures probably is the most tricky part of it all. The poc manipulating the bytecode definitely wouldn't be my first choice though. I'm guessing manipulating the ast should be much less scary and brittle.

I'm guessing manipulating the ast should be much less scary and brittle.

heh
My one good eye is twitching behind its gilt-encrusted monocle. Although the above statement is absolutely true with respect to bytecode manipulation, AST manipulation itself is still scare and brittle. Notably, AST representations change between Python versions. Of course, this has to be the case; if it wasn't, we couldn't improve the core language with new syntactic primitives. :monocle_face:
This means that you usually don't want to directly bang on the output of the core ast module.  Of course, nobody wants to add yet another dependency to anything. You could always do what we do and pretend that your test suite already catches all possible portability issues. If tox ain't worried, we ain't worried!

I could also imagine some possible middleground for closures for the time being. It's much easier to check for closures than changing code on the fly, so we could simply give the user a heads up on unreachable callables and tell them to do it manually. We could always come back to it at a later time..

That's... a stupendous idea, actually. There are just sooo many red-headed level 99 dragons breathing fire across aspectization schemes that depend on fragile bytecode and/or AST manipulation. Emitting non-fatal warnings and/or log messages with the INFO or WARNING levels preserves scarce developer sanity while still enabling end user interventions. Cat @leycec approved. :cat2:

After a couple of busy months and fixing other stuff, I'm revisiting aspectizing, intending to finish what I started.
First I'm implementing an overview of everything that's been decorated by using a generated HTML with CSS & Brython.
The user should also be able to try different filters to get an idea how to adjust their code to get the desired results.
I've successfully realized a similar approach for selecting hashes, where the user can select everything they want and then just click a button to copy&paste a generated snippet ( see https://codepen.io/amogorkon/pen/OJzJgpx ), so I know this will work.
This should help greatly with debugging and overall usability, which is critical (scrolling through thousands of log entries is not very enjoyable and productive, at least for me). As usual, feel free to steal the idea ;-)
Then there are some issues that need to be solved with recursion into modules/packages. Getting reliable info on modules is harder  than I thought. Also - decorating classes? Oh man.
I'm tackling all of the above now. Once I'm done, I - as a user - want to be able to

get a good idea of what's happening for debugging and coding
decorate everything with a general purpose timing decorator to see the actual performance of stuff in real code with statistics
be able to decorate everything fully annotated with numba.njit (and get an idea how much of a performance impact it has with 2.)
be able to decorate everything with beartype to track down typing issues that numba might complain about

Brython

This is the way.

As usual, feel free to steal the idea ;-)

If it's not nailed down, it's already in my backpack.

decorating classes? Oh man.

...heh.
So excited about all of this, @amogorkon! 2021 was a wild ride there, wasn't it? And 2022 is shaping up to be the growling tiger we really wish we weren't riding, but somehow here we are – arms flopping about uselessly and hoping this all ends well.
As for @leycec, I'm on the cusp of finally pushing out a pecuniary GitHub Sponsors profile. Then it's on to ReadTheDocs-hosted documentation that no longer embarrasses the entire @beartype organization. :sweat:

So excited about all of this, @amogorkon! 2021 was a wild ride there, wasn't it?
Indeed it was.
And 2022 is shaping up to be the growling tiger we really wish we weren't riding, but somehow here we are – arms flopping about uselessly and hoping this all ends well.
The writers of the series really outdid themselves this season. Hasn't been as nervewrecking in a long time..
As for @leycec, I'm on the cusp of finally pushing out a pecuniary GitHub Sponsors profile. Then it's on to ReadTheDocs-hosted documentation that no longer embarrasses the entire @beartype organization. 😓
Oh, nice! Wish you great success with that, you earned it 👍

Btw, I'm just pondering an idea regarding aspects. Web messages/exceptions really change the game in what's feasible in terms of usability. What if mod = use("some_mod" with mod @ beartype wouldn't actually apply anything but do a dry run ("what if..") and open a web message with different filters, options etc. for the user to tweak and then copy a proper generated use.apply_aspect(..) snippet to get exactly what they were looking for without guessing about what might or might not get hit?

OMG. You are God-tier Pythonista. I'm not gonna lie, despite commonly doing so; this is phenomenal.
Ignoring @beartype integration for a hot minute, even your oh-so-punny use.woody_logger offers a countably infinite catalogue of insanely useful use cases. You've got embedded profiling, call stack tracing, parameter pretty printing, and so much more going on in that simple example. The killer app is that you didn't even have to instrument the target package itself; justuse just delicately reaches in and quietly instruments everything without the target package even knowing that there's a hand up its kilt.
Gotta ask, though we already know the answer: is any of this aspectization available in justuse 0.6.5 or are we all holding our breath for the next stable release to drop? Because I wanna start @beartype-ing everyone else's code without their consent.
Relatedly, I've opened up a prominent @beartype issue proposing that I document how exactly to go about this. Of course, we currently don't even have documentation in any meaningful sense. That should probably come first. :smiling_face_with_tear:

Hehehe. If you liked woody logger, behold the tinny profiler! I recall you asked for a way to measure the performance impact of applying beartype.
import use, numpy

use.apply_aspect(numpy, use.tinny_profiler)
numpy.zeros((3,3))
use.show_profiling()

produces https://codepen.io/amogorkon/pen/JjMbjgy - still needs a little polishing, but it's getting there.
With that you should be able to assess the impact of applying decorators (I'm considering to add plots to show how timings change over time, but that's no priority atm).
This functionality isn't in 0.6.5, but I managed to get all our unit tests to pass today, so we're actually getting close to ready for the next release. We have a mass test (called "the beast") which attempts to use() pretty much all packages in the conda distribution (~2000 packages). I've simplified it so it all runs in a single parametrized test for 3-4 hours, installing everything in a single process. It's about 70% successful, which is okay-ish for now, but I'd like to have another look and see if there is any big issue we've missed so far that needs to be addressed before we can release it without breaking too much.

Relatedly, I've opened up a https://github.com/beartype/beartype/issues/114. Of course, we currently don't even have documentation in any meaningful sense. That should probably come first. 🥲

The way to apply decorators is going to be:

get an overview of what you're gonna hit with

mod = use(package)
mod @ decorator

which will open a browser window with a list of all callables and you can adjust your filters, then
2. copy&paste the snippet back into your code, leading to a call like
use.apply_aspect(module, decorator, **kwargs)

with the added bonus that the aspectized module doesn't have to be use()d but can also be imported regularly.

We have a mass test (called "the beast") which attempts to use() pretty much all packages in the conda distribution (~2000 packages).

:fearful: → :open_mouth:
Your fearlessness is an example I strive to follow. Also, if I'm speed-reading this right...
use.apply_aspect(module, decorator, **kwargs)

...then @beartype users could conceivably configure the decoration by passing keyword arguments like so:
from beartype import (
    beartype, BeartypeConf, BeartypeStrategy)

# Forcefully stuff linear type-checking into "{module}",
# automating manual decorations resembling:
#     @beartype(conf=BeartypeConf(strategy=BeartypeStrategy.On)
#    def muh_func(...): ...
use.apply_aspect(
    {module},
    beartype,
    conf=BeartypeConf(strategy=BeartypeStrategy.On),
)

Does that grok? Lastly, this also fascinates:
...with the added bonus that the aspectized module doesn't have to be `use()`d but can also be imported regularly.

Ah-ha! So:

use.apply_aspect() actually dynamically monkey-patches in-place all decorateable attributes of the passed {module}. Is that right? If so... that's sick, bro. So, good! Relatedly:

Is there a parallel API for side effect-free aspectization? Perhaps a similar use function that instead produces a proxy target module wrapper object without modifying the underlying source package or module? If so... wicked sick.

 If so... ultimate wicked sick!

from beartype import (
beartype, BeartypeConf, BeartypeStrategy)

use.apply_aspect(
{module},
beartype,
conf=BeartypeConf(strategy=BeartypeStrategy.On),
)

@beartype(conf=BeartypeConf(strategy=BeartypeStrategy.On)
My first thought was that it would simply translate to
use.apply_aspect(module, beartype(conf=BeartypeConf(strategy=BeartypeStrategy.On))
With a nice and simple pre-initialized decorator, which is then applied to everything we can find.. but there's nothing simple about decorators, is it. Are you saying that your decorator has a side effect when initialized and that
decorator = beartype(conf=BeartypeConf(strategy=BeartypeStrategy.On)

def a(x:int) -> int:
   return x ** 2
def b(x:int) -> float:
   return x / 2

a = decorator(a)
b = decorator(b)

wouldn't work because it needs to be re-initialized?
I hope not 🥺

use.apply_aspect() dynamically monkey-patches in-place all decoratable attributes of the passed {module} by globally replacing all relevant source attributes of that module with their decorated target equivalents. Is that right? If so... that's sick, bro.

@beartype
def _wrap(*, thing: Any, obj: Any, decorator: Callable, name: str) -> Any:
    wrapped = decorator(obj)
    _applied_decorators[(thing, name)].append(decorator)
    _aspectized_functions[(thing, name)].append(obj)

    # This will fail with TypeError on built-in/extension types.
    # We handle exceptions outside, let's not betray ourselves.
    setattr(thing, name, wrapped)
    return wrapped

That's all there is.. wait, are you trying to trick me into ast-fiddling?
{module} can be any object though, we just crawl all attributes looking for something of type(x) == type and recurse there. Getting the recursion right was tricky, so were names (qualnames vs. names vs no name at all.. 🚑 ) and a number of other nitty gritty details.. no wonder my newbies ran away 😭

Is there a parallel API for side effect-free aspectization? Perhaps a similar use function that instead produces a proxy target module wrapper object without modifying the underlying source package or module? If so... wicked sick.

What do you mean "side-effect free"? Ohhh.. you mean to decorate not replaceable attributes like numpy extension types? 🤔  Hmm.. use() already returns a ProxyModule, which proxies all method lookups transparently for other reasons already (working module reloading, for one - reminds me to look into aspectizing of ModuleReloader..), so we should be able to wire that in fairly easily. Although having said that, I'm having a feeling there might be a whole pit of dragons to deal with..

Does that also transitively apply to all child submodules when {module} is in fact a package? If so... ultimate wicked sick!
Eh. There is no distinction between package and module at this level. Whatever is imported is considered a module, but I guess you mean to decorate everything that is imported on the user's side.

It actually did and it could again if we removed
        try:
            thing_module_name = inspect.getmodule(thing).__name__
        except AttributeError:
            thing_module_name = "<unknown>"
        if thing_module_name != module_name:
            return

but it was a little too much raw power at that point. It would require more sophisticated Brython to process the thousands of objects in the DOM and display them in a non-headache-inducing manner. I guess the human side is the bottleneck for that one. Also for some reason applying a filter to the 2000 decoratable objects in numpy already takes a few seconds in the browser, which is a domain I yet have very little experience with.

use.apply_aspect(module, beartype(conf=BeartypeConf(BeartypeStrategy.On)))

This is truth. Your first thought is the correct thought. My first thought was derailed onto the rocks below by seeing **kwargs and then running amok with bad assumptions.
Since beartype(conf=BeartypeConf(...)) returns a decorator, the above use case looks great as is. :+1:

Are you saying that your decorator has a side effect when initialized...

Thank Freya, no. @beartype is idempotent (so, side-effect-free), because I'm still sane. I'm also pretty sure anyone publicly qualifying that they're "still sane" is one brick short of a full load.

wait, are you trying to trick me into ast-fiddling?

:eyes:
Actually, I think I just confused all of us.
Please do not disembowel justuse with AST fiddling. It's bad enough that beartype is eventually going to do that. This is a dark road we chosen few walk, @amogorkon.

setattr(thing, name, wrapped)

Ah-ha! So, use.apply_aspect() does indeed dynamically monkey-patch the target module in-place. I think. Actually, I'm still not certain, because my German is still trash despite having watched Run Lola Run 57 times. possibly 58
Just to be clear, does this snippet raise a BeartypeCallHintViolation exception?
import beartype, numpy, use
use.apply_aspect(numpy, beartype)
numpy.zeros('Pretty sure this is balls.')

Pretty sure it does, but I'm obsessively refreshing /r/Ukraine like a mad lad rather than just pulling and installing your master branch like I should be.

...you mean to decorate not replaceable attributes like numpy extension types?

I... actually no longer know what I mean. Not sure I ever did.
Nonetheless, the above question sounds like it leads to a risky and fragile place. This means I support it.

I guess you mean to decorate everything that is imported on the user's side.

Pretty sure I lost the plot a few comments ago. Note to self: never use the term "transitive" unless I myself know what that word means.
Basically, does use.apply_aspect() recurse into subpackages or does it just directly aspectize the passed module? As a selfish example that I now need to try, can we @beartype the entire beartype package (including all subpackages of that package) with a single one-liner like this:
import beartype, use
use.apply_aspect(beartype, beartype)

# Does the above aspectization recursively @beartype
# all functions defined throughout the entire "beartype"
# codebase? If so, the following should raise a
# "BeartypeCallHintViolation" exception.
beartype.vale.Is['This is full-on bollocks, bro.']

...or do we instead have to iteratively @beartype each specific beartype subpackage with another use.apply_aspect() call like this:
import beartype, use
use.apply_aspect(beartype, beartype)
use.apply_aspect(beartype.vale, beartype)  # <-- gotta do this?

# Please raise a "BeartypeCallHintViolation" exception.
beartype.vale.Is['This is full-on bollocks, bro.']

Unrelatedly, Panzerfaust. What a word, that word. Only German can succinctly express violent weaponry and its natural application. There's probably a historical lesson there.

import beartype, numpy, use
use.apply_aspect(numpy, beartype)
numpy.zeros('Pretty sure this is balls.')

Before you do this, you should do
from beartype import beartype
import use
np = use("numpy")
np @ beartype

which will attempt to apply the decorator (and unwrap the callable again) then open a browser tab with a gigantic list of everything callable and potentially decoratable, including info on exceptions that prevent decoration like

I could add the complete exception tracebacks to these, not sure if that would be very useful, though.
BUT use.apply_aspect doesn't raise exceptions itself because that make it very tedious to decorate a large module like numpy since you'd have to manually filter everything on that list that might cause problems.

Nonetheless, the above question sounds like it leads to a risky and fragile place. This means I support it.

Let me find a new minion to work on this.. >_>

Basically, does use.apply_aspect() recurse into subpackages or does it just directly aspectize the passed module? As a selfish example that I now need to try, can we @beartype the entire beartype package (including all subpackages of that package) with a single one-liner like this:

It doesn't recurse beyond the module border, at the moment. That means you'd have to do it like
import beartype, use
use.apply_aspect(beartype, beartype)
use.apply_aspect(beartype.vale, beartype)  # <-- gotta do this?

at least until I find a way to tame this raw power. It's definitely doable to recurse into everything, but it quickly becomes unpredictable because you'd be ehhh... wait a second.
Your usecase doesn't require recursion. The module name for beartype is beartype and the module name for beartype.vale is beartype.vale - and..
for mod in sys.modules:
   if mod.split(".")[0] == "beartype": print(mod))

gives
beartype._decor
beartype.roar._roarexc
beartype.roar._roarwarn
beartype.roar
beartype._decor._code
beartype._util
beartype._util.text
beartype._util.text.utiltextmagic
beartype._decor._code.codesnip
beartype._decor._code._pep
beartype._decor._cache
beartype._util.cache
beartype._util.func
beartype._util.func.utilfuncwrap
beartype._util.utiltyping
beartype._util.func.utilfunccodeobj
beartype._util.func.utilfuncarg
beartype._util.utilobject
beartype._util.text.utiltextlabel
beartype._util.cache.utilcachecall
beartype._util.cls
beartype._util.cls.pep
beartype._util.cls.pep.utilpep3119
beartype._cave
beartype._cave._caveabc
beartype._util.py
beartype._util.py.utilpyversion
beartype._cave._cavefast
beartype._data
beartype._data.cls
beartype._data.cls.datacls
beartype._data.mod
beartype._data.mod.datamod
beartype._util.cls.utilclstest
beartype._util.mod
beartype._util.mod.utilmodimport
beartype._util.os
beartype._util.os.utilostest
beartype._util.py.utilpyinterpreter
beartype.meta
beartype._util.mod.utilmodtest
beartype._decor._cache.cachetype
beartype._util.cache.utilcacheerror
beartype._decor._code._pep._pepmagic
beartype._util.hint
beartype._util.hint.nonpep
beartype._util.hint.nonpep.utilnonpeptest
beartype._cave._cavemap
beartype._decor._code._pep._pepsnip
beartype._util.func.utilfuncscope
beartype._util.hint.pep
beartype._util.hint.pep.proposal
beartype._util.hint.pep.proposal.pep484585
beartype._util.hint.pep.proposal.pep484
beartype._util.hint.pep.proposal.pep484.utilpep484ref
beartype._util.mod.utilmodule
beartype._util.hint.pep.proposal.pep484585.utilpep484585ref
beartype._decor._code._pep._pepscope
beartype._util.cache.pool
beartype._util.cache.pool.utilcachepool
beartype._util.text.utiltextrepr
beartype._util.cache.pool.utilcachepoollistfixed
beartype._util.cache.pool.utilcachepoolobjecttyped
beartype._data.hint
beartype._data.hint.pep
beartype._data.hint.pep.sign
beartype._data.hint.pep.sign.datapepsigncls
beartype._data.hint.pep.sign.datapepsigns
beartype._data.hint.pep.sign.datapepsignset
beartype._util.hint.pep.proposal.pep484.utilpep484generic
beartype._util.hint.pep.proposal.pep484.utilpep484
beartype._util.hint.pep.proposal.utilpep585
beartype._util.hint.pep.proposal.pep484585.utilpep484585
beartype._util.hint.pep.proposal.pep484585.utilpep484585arg
beartype._util.hint.pep.proposal.pep484585.utilpep484585generic
beartype._util.hint.pep.proposal.pep484585.utilpep484585type
beartype._util.text.utiltextjoin
beartype._util.hint.pep.proposal.utilpep586
beartype.vale._factory
beartype._util.kind
beartype._util.kind.utilkinddict
beartype.vale._valevale
beartype.vale._factory._valeisabc
beartype.vale._factory._valeis
beartype.vale._util
beartype.vale._util._valeutilsnip
beartype.vale._factory._valeiscls
beartype.vale._factory._valeisobj
beartype.vale._factory._valeisoper
beartype.vale
beartype._util.hint.pep.proposal.utilpep593
beartype._data.hint.pep.datapeprepr
beartype._util.hint.pep.proposal.pep484.utilpep484newtype
beartype._util.hint.pep.utilpepget
beartype._util.hint.pep.utilpepattr
beartype._util.hint.pep.proposal.utilpep544
beartype._util.hint.pep.utilpeptest
beartype._data.func
beartype._data.func.datafunc
beartype._util.cache.map
beartype._util.cache.map.utilmapbig
beartype._util.hint.pep.proposal.pep484.utilpep484union
beartype._util.hint.utilhinttest
beartype._util.hint.utilhintconv
beartype._util.text.utiltextmunge
beartype._decor._code._pep._pephint
beartype._decor._error
beartype._decor._error._errorsleuth
beartype._decor._error._errortype
beartype._decor._error._pep
beartype._decor._error._pep._pep484
beartype._decor._error._pep._pep484._errornoreturn
beartype._decor._error._pep._pep484._errorunion
beartype._decor._error._pep._pep484585
beartype._decor._error._pep._pep484585._errorgeneric
beartype._decor._error._pep._pep484585._errorsequence
beartype._decor._error._pep._errorpep586
beartype._decor._error._pep._errorpep593
beartype._decor._error.errormain
beartype._util.func.utilfunctest
beartype._decor._data
beartype._decor._code._pep.pepcode
beartype._util.hint.pep.proposal.pep484585.utilpep484585func
beartype._decor._code.codemain
beartype._util.func.lib
beartype._util.func.pep
beartype._util.func.pep.utilpep484func
beartype._util.mod.lib
beartype._util.func.utilfuncstack
beartype._util.mod.lib.utilsphinx
beartype._util.func.lib.utilbeartypefunc
beartype._util.func.utilfuncmake
beartype._decor.main
beartype
beartype._util.text.utiltextident
beartype._decor._pep563
beartype._util.func.utilfuncfile
beartype._util.hint.pep.proposal.utilpep589

Which means we could simply pick stuff from sys.modules.. (and I wanted to get rid of the import caching, maybe finally a redeeming quality).

Unrelatedly, Panzerfaust. What a word, that word.

Fascinating how I was thinking the same thing the other day.. 🤯

BUT use.apply_aspect doesn't raise exceptions itself because that make it very tedious to decorate a large module like numpy since you'd have to manually filter everything on that list that might cause problems.

It is sane. Thus, this is the only way that matters.
That said, would an optional use.apply_aspect(..., *, warns: bool = False) boolean keyword parameter named warns (or something something) be trivial enough to make your precious time worthwhile? Passing use.apply_aspect(..., warns=True) might emit one non-fatal warning for each undecoratable object (possibly embedding the exception message originating that warning). The output would be gargantuan and stinky – which is why sane devs such as ourselves pipe that wretched mess into less.
Maybe? If easy-peasy, that could be nice because Pythonic and CLI-driven. If non-easy-peasy, we forget the last paragraph and return to binging Severance for the good of Apple revenue.

Your usecase doesn't require recursion.

Hold my beer:
>>> import beartype, sys
>>> for mod in sys.modules:
...   if mod.split(".")[0] == "beartype": print(mod)
beartype.meta
beartype._decor
beartype._util
beartype._util.py
beartype._util.py.utilpyversion
beartype._util.cache
beartype.roar._roarexc
beartype.roar._roarwarn
beartype.roar
beartype._util.func
beartype._util.func.arg
beartype._util.func.utilfuncwrap
beartype._data
beartype._data.datatyping
beartype._util.func.utilfunccodeobj
beartype._util.func.arg.utilfuncargtest
beartype._util.text
beartype._util.utilobject
beartype._util.text.utiltextlabel
beartype._util.cache.utilcachecall
beartype.typing._typingpep544
beartype.typing
beartype._decor.conf
beartype._decor.cache
beartype._data.cls
beartype._cave
beartype._cave._caveabc
beartype._cave._cavefast
beartype._data.cls.datacls
beartype._decor._code
beartype._util.error
beartype._util.error.utilerror
beartype._decor._code.codemagic
beartype._util.cls
beartype._util.cls.pep
beartype._util.cls.pep.utilpep3119
beartype._data.mod
beartype._data.mod.datamod
beartype._util.cls.utilclstest
beartype._util.mod
beartype._util.mod.utilmodimport
beartype._util.mod.utilmodtest
beartype._decor.cache._cachetype
beartype._decor._error
beartype._util.hint
beartype._util.hint.nonpep
beartype._util.hint.nonpep.utilnonpeptest
beartype._cave._cavemap
beartype._data.hint
beartype._data.hint.pep
beartype._data.hint.pep.sign
beartype._data.hint.pep.sign.datapepsigncls
beartype._data.hint.pep.sign.datapepsigns
beartype._data.hint.pep.sign.datapepsignset
beartype._util.hint.pep
beartype._data.hint.pep.datapeprepr
beartype._util.hint.pep.proposal
beartype._util.hint.pep.proposal.pep484
beartype._util.hint.pep.proposal.pep484.utilpep484newtype
beartype._util.hint.pep.proposal.utilpep585
beartype._util.hint.pep.utilpepget
beartype._util.hint.pep.proposal.pep484.utilpep484
beartype._util.hint.pep.proposal.utilpep544
beartype._util.hint.pep.proposal.utilpep593
beartype._util.mod.utilmodule
beartype._util.hint.pep.utilpeptest
beartype._data.func
beartype._data.func.datafunc
beartype._util.cache.map
beartype._util.cache.map.utilmapbig
beartype._util.hint.pep.proposal.pep484.utilpep484union
beartype._util.hint.pep.proposal.utilpep557
beartype._util.hint.utilhinttest
beartype._util.hint.utilhintconv
beartype._decor._error._errorsleuth
beartype._util.text.utiltextmunge
beartype._util.text.utiltextrepr
beartype._util.hint.pep.proposal.pep484585
beartype._util.hint.pep.proposal.pep484.utilpep484ref
beartype._util.hint.pep.proposal.pep484585.utilpep484585ref
beartype._util.hint.pep.proposal.pep484585.utilpep484585arg
beartype._util.hint.pep.proposal.pep484585.utilpep484585type
beartype._util.text.utiltextjoin
beartype._decor._error._errortype
beartype._decor._error._pep
beartype._decor._error._pep._pep484
beartype._decor._error._pep._pep484._errornoreturn
beartype._decor._error._pep._pep484._errorunion
beartype._decor._error._pep._pep484585
beartype._util.hint.pep.proposal.pep484.utilpep484generic
beartype._util.hint.pep.proposal.pep484585.utilpep484585generic
beartype._decor._error._pep._pep484585._errorgeneric
beartype._util.hint.pep.proposal.pep484585.utilpep484585
beartype._decor._error._pep._pep484585._errorsequence
beartype._util.hint.pep.proposal.utilpep586
beartype._decor._error._pep._errorpep586
beartype._util.text.utiltextmagic
beartype._decor._error._pep._errorpep593
beartype._decor._error.errormain
beartype._util.func.utilfuncscope
beartype._util.func.utilfunctest
beartype._decor._call
beartype._decor._code.codesnip
beartype._decor._code._pep
beartype._decor._code._pep._pepmagic
beartype._util.func.arg.utilfuncargiter
beartype._decor._code._pep._pepsnip
beartype._decor._code._pep._pepscope
beartype._util.cache.pool
beartype._util.cache.pool.utilcachepool
beartype._util.cache.pool.utilcachepoollistfixed
beartype._util.cache.pool.utilcachepoolobjecttyped
beartype._util.kind
beartype._util.kind.utilkinddict
beartype._decor._code._pep._pephint
beartype._util.hint.pep.proposal.pep484585.utilpep484585func
beartype._decor._code.codemain
beartype._util.cls.pep.utilpep557
beartype._util.func.lib
beartype._util.func.pep
beartype._util.func.pep.utilpep484func
beartype._util.mod.lib
beartype._util.func.utilfuncstack
beartype._util.mod.lib.utilsphinx
beartype._util.func.lib.utilbeartypefunc
beartype._util.func.utilfuncmake
beartype._decor._core
beartype._decor.cache.cachedecor
beartype._decor.main
beartype

Thankfully (or not), beartype.vale isn't there. Praise Jeebus! B-b-but... how could this be? Well, it turns out that the beartype codebase goes out of its way to import as little as possible at global scope.
Obviously, we failed. I mean, just look at that list. We're still internally importing way too much at global scope. So that I can sleep tonight, let's pretend I didn't see that.
This includes beartype.vale, which is (mostly) only ever imported when a user explicitly imports from that subpackage.
Annnnnyway. Recursion is an understandable nest of vipers in Python, because we don't have tail recursion or other obvious (but necessary) optimizations. You can't safely even do recursion in Python without blowing up the stack.
This is why I'm now going to drown my sorrows in a bucket of Netflix-fueled anime. Time to forget my troubles, everybody! :tv:

That said, would an optional use.apply_aspect(..., *, warns: bool = False) boolean keyword parameter named warns (or something something) be trivial enough to make your precious time worthwhile? Passing use.apply_aspect(..., warns=True) might emit one non-fatal warning for each undecoratable object (possibly embedding the exception message originating that warning). The output would be gargantuan and stinky – which is why sane devs such as ourselves pipe that wretched mess into less.

Sounds good. Question is whether you'd prefer raise or warn or print or a combination of those.
If you're thinking of piping it anyway, I could do you one better and add an output or file keyword argument which could be plugged into print()  to pipe the output to the specified target directly. Then you'd get a
use.apply_aspect(mod, beartype, warns=True, output="bear-problems.log")

Annnnnyway. Recursion is an understandable nest of vipers in Python, because we don't have tail recursion or other obvious (but necessary) optimizations. You can't safely even do recursion in Python without blowing up the stack.

Well, technically this is true for deep recursion, but we're not even talking about very deep recursion here so it is an option actually.     .oO(Maybe you're crazy enough to come up with a viable solution 😈 )
The issue with recursion in this case is this: When you're starting to check an object like a module for a __dict__ to recurse into, you're first recursing into all the imports (stdlib, external libs, everything) but also into class-parents, including object itself and from there into everything - everything is connected with each other and before you know it you're decorating the whole planet 💥 .
So, I tried to come up with ways to limit the effects in some meaningful way, but it's kinda hard to balance between too strict and too lax. I definitely see the benefits of being less strict, but 1) how to communicate this to the user (displaying and filtering 10k objects in a browser may not be easily feasible) 2) any ideas what could be meaningful limits?
I'm thinking that we could keep the module (most strict) as default "blast radius" but have a keyword with an enum flag to increase the affected area like use.apply_aspect(mod, beartype, affect=package | dependencies) or somesuch..
What do you think?

Ugh. Just realized I never replied to this awesomeness. Since I'm exhausted, that can't happen tonight. Let's rain check for this a deep dive later this week.  :thinking:
Thanks as always for being so inspirational, irrepressible, and smart, @amogorkon!

Phew! What a week, that last week. Let's discombobulate this.

Question is whether you'd prefer raise or warn or print or a combination of those.

I choose you, warn and/or warns! That said, that's @beartype for you. We raise exceptions all over the place. raise would destroy everything. For other decorators that raise exceptions less frequently (...so, less fragile decorators is what I'm saying), raise could very well be the Right Thing.™
print is probably subsumed by either raise or warn – maybe? After all, warnings and exceptions can always be redirected to the requisite open file handle. So, raise and warn >>>>> print. maybe

I could do you one better and add an output or file keyword argument which could be plugged into print() to pipe the output to the specified target directly.

Yes. I vote for file, but a file parameter whose value must be an open file handle rather than a stringified filename. This approach is the Big Boss, because users can then pass anything that satisfies the typing.TextIO protocol – including io.StringIO objects and the standard sys.stdout and sys.stderr streams: e.g.,
from sys import stderr

# Punt all decoration exceptions to stderr, yo!
use.apply_aspect(mod, beartype, file=stderr)

# Punt all decoration exceptions to my 1TB-large logfile!
with open('bear-problems.log') as you_didnt_see_nuffin:
    use.apply_aspect(mod, beartype, file=you_didnt_see_nuffin)

...before you know it you're decorating the whole planet :boom: .

:exploding_head:

I'm thinking that we could keep the module (most strict) as default "blast radius"...

Yup. Explicit is better than implicit. Minimizing the explosive potential minimizes user migraines and old-age tinnitus. Thanks a lot, decades of reckless listening to German power metal at unhealthy volumes!
Relevantly, I just tripped across this deep StackOverflow post non-recursively iterating over the full transitive set of all submodules of a given package under Python ≥ 3.6:
import importlib, pkgutil, sys

def find_abs_modules(module):
    path_list = []
    spec_list = []
    for importer, modname, ispkg in pkgutil.walk_packages(module.__path__):
        import_path = f"{module.__name__}.{modname}"
        if ispkg:
            spec = pkgutil._get_spec(importer, modname)
            importlib._bootstrap._load(spec)
            spec_list.append(spec)
        else:
            path_list.append(import_path)
    for spec in spec_list:
        del sys.modules[spec.name]
    return path_list

Of course, there's a bit of unhealthy modification of global state (e.g., sys.modules) up there – but anyone deploying justuse-based aspectization in the first place is probably already prepared for bombshells like that.

...have a keyword with an enum flag to increase the affected area like use.apply_aspect(mod, beartype, affect=package | dependencies)

Totally fascinating. Love that |-style union set operator abuse, too. Alternately, you could also defer responsibility to the user with a similar parameter accepting an explicit blast radius of all package and module names to be aspectized: e.g.,
import use
`use.apply_aspect(mod, beartype, affect=use.iter_submodules(mod))`

Here, the hypothetical use.iter_submodules() function (which probably just resembles the above find_abs_modules() function) either yields or returns an iterable of the fully-qualified names of all submodules and subpackages of the passed module or package.
Ultimate API victory is now within sight! :hushed:

Wow, lots of good stuff right there. Hmm.. your hypothetical iter_submodules function intrigues me. What if apply_aspect could take an iterable[mod] as first parameter instead? We could simplify the signature for apply_aspect(mod: Any | Iterable[ModuleType], decorator: Callable) special casing Iterable[ModuleType] so you could (actually, using https://github.com/robinhilliard/pipes) do use.iter_submodules(mod) >> use.apply_aspect(beartype)

What if apply_aspect could take an iterable[mod] as first parameter instead?

So much, "YESSSS!!!" Generalize that first parameter up.

https://github.com/robinhilliard/pipes

...what is this madness I've always yearned for in my life?
Where did you even find out about that hidden gem, if I might pry deeply into your clandestine browsing habits? pipes only has 48 GitHub stars, so it's still early days for them. Incredibly impressive regardless; the first thing I thought when I saw that deadly syntactic brew wasn't Elixir-style piping but C++-style output stream redirection. The nostalgia is profound.
Actually, I'm wondering now if the latter inspired the former... Of course, no one would (or should) ever publicly admit that. ...heh

use.iter_submodules(mod) >> use.apply_aspect(beartype)

:hot_face:

use.apply_aspect(use.iter_submodules(mod), beartype)

:sunglasses:
If you do end up leveraging the @pipes.pipes decorator, consider only doing so conditionally when pipes is installed as an optional runtime dependency. I've learned through the ongoing school of real-world pain to avoid mandatory dependencies wherever feasible – which is everywhere.
So excited about all this awesome sauce, @amogorkon.

Where did you even find out about that hidden gem, if I might pry deeply into your clandestine browsing habits? pipes only has 48 GitHub stars, so it's still early days for them.

I was venturing into functional-land and was looking for a way to untangle a deeply nested (()) mess. The obvious (but imo wrong) solution is to overload | to wrap __call__ etc. which I've also initially fiddled with, and there's also https://pypi.org/project/pipe/ which does this, but the problem with this approach is that many built-in functions (like map) have their second/last positional argument to iterate over, which requires rewriting a lot of code (or monkeypatching). Another issue with this approach is that it doesn't really make the code simpler in my opinion but introduces even more convolution.
look at print(sum(range(100) | select(lambda x: x ** 2) | where(lambda x: x < 100))) (from pipe README) and compare that to
@pipes
def foo():
    (
    range(100)
    << map(lambda x: x**2)
    << filter(lambda x: x < 100)
    >> sum
    >> print
    )

so, yeah. The << and >> need a bit of getting used to, but it's a small sacrifice compared to rewriting those builtins, I think, and it's much cleaner.
Ever since I found it, I've been lobbying for it, but there's clearly a visibility problem (probably also because it was labelled beta and it hasn't been touched in 4 years, but considering it's just 50 lines of code and it just works...)

If you do end up leveraging the @pipes.pipes decorator, consider only doing so conditionally when pipes is installed as an optional runtime dependency. I've learned through the ongoing school of real-world pain to avoid mandatory dependencies wherever feasible – which is everywhere.

Oh no, I wouldn't force a dependency like this on anyone! However, pipes is so small, I actually pasted the few lines in  https://github.com/amogorkon/justuse/blob/unstable/src/use/tools.py, putting it to good use in https://github.com/amogorkon/justuse/blob/unstable/src/use/pimp.py 😁 👼

Where did you even find out about that hidden gem, if I might pry deeply into your clandestine browsing habits? pipes only has 48 GitHub stars, so it's still early days for them.

I was venturing into functional-land and was looking for a way to untangle a deeply nested (()) mess. The obvious (but imo wrong) solution is to overload | to wrap __call__ etc. which I've also initially fiddled with, and there's also https://pypi.org/project/pipe/ which does this, but the problem with this approach is that many built-in functions (like map) have their second/last positional argument to iterate over, which requires rewriting a lot of code (or monkeypatching). Another issue with this approach is that it doesn't really make the code simpler in my opinion but introduces even more convolution.
look at print(sum(range(100) | select(lambda x: x ** 2) | where(lambda x: x < 100))) (from pipe README) and compare that to
@pipes
def foo():
    (
    range(100)
    << map(lambda x: x**2)
    << filter(lambda x: x < 100)
    >> sum
    >> print
    )

so, yeah. The << and >> need a bit of getting used to, but it's a small sacrifice compared to rewriting those builtins, I think, and it's much cleaner.
Ever since I found it, I've been lobbying for it, but there's clearly a visibility problem (probably also because it was labelled beta and it hasn't been touched in 4 years, but considering it's just 50 lines of code and it just works...)

If you do end up leveraging the @pipes.pipes decorator, consider only doing so conditionally when pipes is installed as an optional runtime dependency. I've learned through the ongoing school of real-world pain to avoid mandatory dependencies wherever feasible – which is everywhere.

Oh no, I wouldn't force a dependency like this on anyone! However, pipes is so small, I actually pasted the few lines in  https://github.com/amogorkon/justuse/blob/unstable/src/use/tools.py, putting it to good use in https://github.com/amogorkon/justuse/blob/unstable/src/use/pimp.py 😁 👼

I'm just toying with all the cool new ideas we came up with, but your suggested iter_submodules turns out to be much trickier than I thought, since numpy seems to be allergic to any importlib._bootstrap._load(spec) tricks. If I remove the module import-sideeffect like
def iter_submodules(module: ModuleType) -> Iterable[ModuleType]:
    for importer, modname, ispkg in pkgutil.walk_packages(module.__path__):
        if not ispkg and (mod := sys.modules.get(f"{module.__name__}.{modname}")):
            yield mod

it only produces a minimal list...

I think I finally figured it out now!
import ast, sys, beartype, numpy

def get_imports_from_module(mod):
    if not hasattr(mod, "__file__"):
        return
    with open(mod.__file__, "rb") as file:
        for x in ast.walk(ast.parse(file.read())):
            if isinstance(x, ast.Import):
                name = x.names[0].name
                if name in sys.modules:
                    yield name
            if isinstance(x, ast.ImportFrom):
                name = x.module
                if name in sys.modules:
                    yield name

def get_submodules(mod, names=None):
    if not names:
        names = set()
    for name in get_imports_from_module(mod):
        names.add(name)
        if name in names:
            continue
        for x in get_imports_from_module(sys.modules[name]):
            get_submodules(sys.modules[x], names)
    return names

print(list(get_submodules(beartype)))
print(list(get_submodules(numpy)))

returns ['beartype._decor.main', 'beartype.meta'] and ['numpy.config', 'warnings', 'builtins', 'numpy._pytesttester', 'os', 'sys']
It's exactly what the module you're pointing at imported (recursively) at this point - no extra imports, no side-effects. The only limitation is that the module needs a valid __file__ that can be opened.

I think I finally figured it out.
This is much more involved than I anticipated, but I think this is actually what we want..
import ast, contextlib, sys
from pathlib import Path
import matplotlib

def is_builtin(name, mod):
    if name in sys.builtin_module_names:
        return True

    if hasattr(mod, "__file__"):
        relpath = Path(mod.__file__).parent.relative_to(
                (Path(sys.executable).parent / "lib"))
        if relpath == Path():
            return True
        if relpath.parts[0] == "site-packages":
            return False
    return True

def get_imports_from_module(mod):
    if not hasattr(mod, "__file__"):
        return
    with open(mod.__file__, "rb") as file:
        with contextlib.suppress(ValueError):
            for x in ast.walk(ast.parse(file.read())):
                if isinstance(x, ast.Import):
                    name = x.names[0].name
                    if (mod := sys.modules.get(name)) and not is_builtin(name, mod):
                        yield name
                if isinstance(x, ast.ImportFrom):
                    name = x.module
                    if (mod := sys.modules.get(name)) and not is_builtin(name, mod):
                        yield name

def get_submodules(mod, visited=None, results=None):
    if results is None:
        results = set()
    if visited is None:
        visited = set()
    for name in get_imports_from_module(mod):
        if name in visited:
            continue
        visited.add(name)
        results.add(name)
        for x in get_imports_from_module(sys.modules[name]):
            results.add(x)
            get_submodules(sys.modules[x], visited, results)
    return results

for get_submodules(matplotlib) this actually returns

{'numpy.config', 'matplotlib', 'cycler', 'PIL', 'numpy.core._multiarray_umath', 'matplotlib.fontconfig_pattern', 'matplotlib.cbook', 'matplotlib._api', 'PIL.PngImagePlugin', 'pyparsing', 'matplotlib._api.deprecation', 'numpy', 'packaging.version', 'matplotlib.rcsetup', 'matplotlib._cm', 'matplotlib._cm_listed', 'matplotlib.colors', 'matplotlib.cm', 'matplotlib._enums', 'numpy._pytesttester'}

which means it really seems to hit all non-builtin dependencies that are currently imported without any side-effects and no additional imports.
for get_submodules(beartype) this list is a little longer:

{'beartype._cave._caveabc',
'beartype._cave._cavefast',
'beartype._cave._cavemap',
'beartype._data.cls.datacls',
'beartype._data.func.datafunc',
'beartype._data.hint.pep.datapeprepr',
'beartype._data.hint.pep.sign',
'beartype._data.hint.pep.sign.datapepsigncls',
'beartype._data.hint.pep.sign.datapepsigns',
'beartype._data.hint.pep.sign.datapepsignset',
'beartype._data.mod.datamod',
'beartype._decor._cache.cachetype',
'beartype._decor._code._pep._pephint',
'beartype._decor._code._pep._pepmagic',
'beartype._decor._code._pep._pepscope',
'beartype._decor._code._pep._pepsnip',
'beartype._decor._code._pep.pepcode',
'beartype._decor._code.codemain',
'beartype._decor._code.codesnip',
'beartype._decor._data',
'beartype._decor._error._errorsleuth',
'beartype._decor._error._errortype',
'beartype._decor._error._pep._errorpep586',
'beartype._decor._error._pep._errorpep593',
'beartype._decor._error._pep._pep484._errornoreturn',
'beartype._decor._error._pep._pep484._errorunion',
'beartype._decor._error._pep._pep484585._errorgeneric',
'beartype._decor._error._pep._pep484585._errorsequence',
'beartype._decor._error.errormain',
'beartype._decor.main',
'beartype._util.cache.map.utilmapbig',
'beartype._util.cache.pool.utilcachepool',
'beartype._util.cache.pool.utilcachepoollistfixed',
'beartype._util.cache.pool.utilcachepoolobjecttyped',
'beartype._util.cache.utilcachecall',
'beartype._util.cache.utilcacheerror',
'beartype._util.cls.pep.utilpep3119',
'beartype._util.cls.utilclstest',
'beartype._util.func.lib.utilbeartypefunc',
'beartype._util.func.pep.utilpep484func',
'beartype._util.func.utilfuncarg',
'beartype._util.func.utilfunccodeobj',
'beartype._util.func.utilfuncmake',
'beartype._util.func.utilfuncscope',
'beartype._util.func.utilfuncstack',
'beartype._util.func.utilfunctest',
'beartype._util.func.utilfuncwrap',
'beartype._util.hint.nonpep.utilnonpeptest',
'beartype._util.hint.pep.proposal.pep484.utilpep484',
'beartype._util.hint.pep.proposal.pep484.utilpep484generic',
'beartype._util.hint.pep.proposal.pep484.utilpep484newtype',
'beartype._util.hint.pep.proposal.pep484.utilpep484ref',
'beartype._util.hint.pep.proposal.pep484.utilpep484union',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585arg',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585func',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585generic',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585ref',
'beartype._util.hint.pep.proposal.pep484585.utilpep484585type',
'beartype._util.hint.pep.proposal.utilpep544',
'beartype._util.hint.pep.proposal.utilpep585',
'beartype._util.hint.pep.proposal.utilpep586',
'beartype._util.hint.pep.proposal.utilpep593',
'beartype._util.hint.pep.utilpepattr',
'beartype._util.hint.pep.utilpepget',
'beartype._util.hint.pep.utilpeptest',
'beartype._util.hint.utilhintconv',
'beartype._util.hint.utilhinttest',
'beartype._util.kind.utilkinddict',
'beartype._util.mod.lib.utilsphinx',
'beartype._util.mod.utilmodimport',
'beartype._util.mod.utilmodtest',
'beartype._util.mod.utilmodule',
'beartype._util.os.utilostest',
'beartype._util.py.utilpyinterpreter',
'beartype._util.py.utilpyversion',
'beartype._util.text.utiltextjoin',
'beartype._util.text.utiltextlabel',
'beartype._util.text.utiltextmagic',
'beartype._util.text.utiltextmunge',
'beartype._util.text.utiltextrepr',
'beartype._util.utilobject',
'beartype._util.utiltyping',
'beartype.meta',
'beartype.roar',
'beartype.roar._roarexc',
'beartype.roar._roarwarn',
'beartype.vale._valevale'}

is this the list of modules you were looking for?

Aaaaaand another breakthrough! 😄
Behold - working class decorators!
def woody_logger(thing: Callable) -> Callable:
    """
    Decorator to log/track/debug calls and results.

    Args:
        func (function): The function to decorate.
    Returns:
        function: The decorated callable.
    """
    if isinstance(thing, type):
        class wrapper(thing.__class__):
            def __new__(cls, *args, **kwargs):
                print(f"{args} {kwargs} -> {thing.__name__}()")
                before = perf_counter_ns()
                res = thing(*args, **kwargs)
                after = perf_counter_ns()
                print(
                    f"-> {thing.__name__}() (in {after - before} ns ({round((after - before) / 10**9, 5)} sec) -> {type(res)}"
                )
                return res

    else:
        @wraps(thing)
        def wrapper(*args, **kwargs):
            print(f"{args} {kwargs} -> {_qualname(thing)}")
            before = perf_counter_ns()
            res = thing(*args, **kwargs)
            after = perf_counter_ns()
            print(
                f"-> {_qualname(thing)} (in {after - before} ns ({round((after - before) / 10**9, 5)} sec) -> {res} {type(res)}"
            )
            return res

    return wrapper

So much goodness to unpack here.

I was venturing into functional-land...

Ahh, yes. The age-old software idiom for "In a land far, far away..." is how all good stories start.
Lemme grab the stale week-old popcorn. :popcorn:

...and was looking for a way to untangle a deeply nested (()) mess.

You're triggering my Emacs Lisp PTSD here.
True story: Emacs pinky physically crippled the pinky fingers on both of my hands... permanently. Don't repeat my mistakes, younger generation. Friends don't let friends Emacs.

However, pipes is so small, I actually pasted the few lines in...

This is the way. The @beartype codebase is littered with the bones of other dead projects I've picked clean of juicy marrow and assimilated into my own skeletal frame.
:meat_on_bone: :arrow_right: :bone:

The << and >> need a bit of getting used to...

No, you've nailed it. That's really a brilliant take: since a single overloaded symbol like | fails to generalize to divergent calling conventions (e.g., passing an operand as the second rather than first parameter to a function), only a pair of symmetric overloaded symbols like >> and << suffices.

is this the list of modules you were looking for?

Hole-in-one. That's exactly it. I applaud thunderously from the bleachers while also acknowledging the immense buckets of sweat, blood, and tears that probably went into making that AST import parser happen. Your genius is on a raised plateau of its own.
The upcoming beartype 0.11.0 release will probably also implement some form of recursive import hooking to magically apply @beartype to an entire package or module. I must warn you: your code is hot, I trust you more than I do me, and the <Ctrl>, <c>, and <v> keys on my keyboard are worn out from decades of furious copy-pasting.
What I'm saying here is... I may desperately pilfer the  AST import parser you hand-built above for our own perfidious purpose. If I do this, I will loudly point everyone towards justuse and advise they use your package instead of our crude facsimile. :loudspeaker: :wavy_dash:
Lastly, this is...
def woody_logger(thing: Callable) -> Callable:
    ...
    if isinstance(thing, type):
        class wrapper(thing.__class__):
            def __new__(cls, *args, **kwargs):
                ...

Forehead-smacking cleverness! You're now going to hate me just a little bit harder, but... it's apparently possible for thing to prohibit subclassing with metaclass trickery: e.g.,
>>> class FinalMeta(type):
...    def __new__(cls, name, bases, classdict):
...        for b in bases:
...            if isinstance(b, Final):
...                raise TypeError("type '{0}' is not an acceptable base type".format(b.__name__))
...        return type.__new__(cls, name, bases, dict(classdict))
>>> class FinalType(metaclass=FinalMeta): ...
>>> class ThisRaisesAHorribleException(FinalType): ...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __new__
TypeError: type 'FinalType' is not an acceptable base type

It's best to forget you saw that. I already did, in fact.


⚠ ClamAV has degraded performance

In d83199b, ClamAV (https://spamassassin.apache.org/) experienced degraded performance:

HTTP code: 200
Response time: 595 ms

Resolved: ClamAV performance has improved in f8c6c63.


release v3.4.0 do not contain a fetch.umd.js

the latest fetch.umd.js is v3.3.1

It does contain it --><EMAIL_ADDRESS>

@JakeChampion oh, it does not show a link in github release

Ah yes, thank you for pointing that out, I've now fixed that 👍


fix: reconcile system meterdefs

Ticket:
https://zenhub.ibm.com/workspaces/symposium-workflow-5c49e21b79c5ae72931da0d6/issues/symposium/track-and-plan/23520
Changes:

Updated meterbase_controller to include a watch on System MeterDefinitions, and it reconciles when they are updated or deleted.

@ab-ibm and @mxpaspa - if you could review this PR as well.

Verified with 2.7.1-beta.1099. Default MD were recreated after removal.


Switch to use only class syntax for mutation type

Fix CI error with add_type when testing without TESTING_INTERPRETER:
gems/graphql-1.10.2/lib/graphql/schema.rb:1767:in `add_type':
Can't add legacy type: Mutation (GraphQL::ObjectType) (ArgumentError)

This new failure appears to be related to graphql-1.10.2 vs graphql-1.10.1. This technically deletes some coverage from this PR, but the history around the changes wasn't clear:

a6e58f626764aedba9e2b9858c91a64e454486dc (introduced TESTING_INTERPRETER to test using GraphQL::Execution::Interpreter / GraphQL::Analysis::AST
75bfef9b98faa15b59ee5df7f6ba1253083d7ee2 (fixed bug with non-class mutations)

Is it still standard to use a non-class mutation root / needed to test? If not can delete, otherwise may need to add support with 1.10.2.

Is it still standard to use a non-class mutation root / needed to test? If not can delete, otherwise may need to add support with 1.10.2.

Since this gem still supports the old legacy mutations we should ideally keep this test coverage and instead fix it. I think the first step is updating the Gemfile to use 1.10.2 instead of 1.10.0.pre2 and make sure everything is actually working.

Trace for this error is:
https://github.com/rmosolgo/graphql-ruby/blob/master/lib/graphql/schema.rb#L1767
It looks like this feature is not supported in the graphql-ruby  gem (can see the problem when bumping from v1.9.19 to v1.10.0 of GraphQL).
Here's a minimal reproducing of the error:
require 'graqphl'

MutationType = GraphQL::ObjectType.define do
  name "Mutation"
end

class Schema < GraphQL::Schema
  mutation MutationType
end

https://github.com/rmosolgo/graphql-ruby/blob/master/CHANGELOG.md#deprecations-1
Given that graphql-ruby is not supporting does it still make sense to try and maintain this spec? Could version lock a release via this to indicate also:
spec.add_runtime_dependency "graphql", ">= 1.10", "< 2"`

Ah... the issue is that we're always getting 1.10 now that it's a non-pre release. We'll need to fix CI (and the conditional tests/Gemfile) to test two different versions: <1.10 (really 1.9) and then >= 1.10.
I think it's worthwhile to still have the current version (and the next release) of graphql-batch support both of those transparently.

@swalkinshaw adjusted to test versions + renamed testing env.
It sounds like you'd be open to merging a PR that drops support once the next version of graphql-batch goes live? If so - keeping this PR handy: https://github.com/ksylvest/graphql-batch/pull/1

Thank you 🎉


Add alt tag to img element

Fix accessibility issue by adding alt attribute to img element.
@maxkfranz Would you please take a look?  Thanks

Could you describe the use case for your PR and the intended result?

Hi, @maxkfranz We run accessibility checking tools to make sure the page is readable by screen readers.  For images, screen readers relies on "alt" attribute so it can read.  Hence adding this alt attribute.  Thanks!

Hi, @maxkfranz could you please take a look asap?  We need to release our product in a couple of days.
Thanks

Hi, @maxkfranz could you please take a look asap? We need to release our product in a couple of days.
Thanks


For #1161 part 3: detect template for free assets

For #1161 part 3: definitive fix in ocean.py download_file(), for free assets that are using "free" or "enterprise template" .
Idea is simple:

detect template type
if templateId == 1 :

if wallet has >= 1.0 , then call dt.startOrder()

else check for dispensers. if found, fetch 1 dt from dispenser, call dt.startOrder

if templateId == 2 :

if wallet has >= 1.0 , then call dt.startOrder()

else check for dispensers. if found, call dt.buy_from_dispenser_and_order()

else check for fixedrate. if found, call dt.buy_from_fre_and_order()

From the description:

What if asset has a fixed rate exchange? We always assume that we have a dispenser
Nope. It works for fixed-rate exchange. See the code it checks that "bal > 1.0"

What if tomorrow we will deploy a new Dispenser template, because we have found a bug? Than ocean.py will not be able to download old assets, because it's using the dispenser contract address from addresses.json

This is a separate issue, see #1164
To keep the description clean (and accurate), I've updated it accordingly.

Idea is simple:
- detect template type
- if templateId == 1 : get dt from dispenser, call dt.startOrder
- if templateId == 2 : call dt.buy_from_dispenser_and_order

This proposed algorithm does not cover the case of fixed price, where the user has already acquired the datatoken.
templateid == 1:

status quo code already handles fixed price: it checks if "bal > 1.0" (from a purchase in a prior tx). Bonus: no need to call dispense() for free assets.
If that behavior was changed to the proposal get dt from dispenser, call dt.startOrder, then it would be reducing the functionality. Recommend: leave behavior as-is

templateid == 2:

status quo code did not handle templateid == 2 at all, basically
doing call dt.buy_from_dispenser_and_order only handles free. It should also handle if "bal > 1.0" (from a purchase in a prior tx)

idea is simple:
detect template type

if templateId == 1 : get dt from dispenser, call dt.startOrder
if templateId == 2 : call dt.buy_from_dispenser_and_order

Just to be clear: download_file() already works for both templateid == 1 and 2

if user already has >= 1.0 datatokens, it uses that. (User could have got that via a fixed-rate exchange, transfer, whatever)
otherwise, if asset is free, it can dispense it if allowed_swapper = ZERO

So we don't want to change the algorithm to the "simple" idea above, which only works for free assets
The issue here is that people are trying to download files, that are free and have allowed_swapper != ZERO.

They're surprised that they can't, even though allowed_swapper != ZERO means they shouldn't be able to.
Nonetheless we can do a workaround for this case, by exploiting a quirk in Datatoken.sol::buy_from_dispenser_and_order(): it doesn't care about value of allowed_swapper.

as discussed earlier with @trentmc , with this PR, we have added a lot of code in ocean_assets.py, and we should refactor it in another PR.
at least for now, ocean.py works with both templates, and all price schemas

I just realized: given the large change this PR - including a lot of copy-and-paste due to having to deal with unwieldy interfaces, I propose:

first go do #1207 "Unwieldy interfaces for DatatokenEnterprise.buy_from_dispenser_and_order() and buy_from_fre_and_order()"
and maybe other ocean.py work that's also causing large copy-and-paste here
then come back to this PR

@calina-c @alexcos20 I believe that we can close this issue now:

there was a bunch of work, mostly done by Calina, for clean interfaces & implementations that also solves the problem of this github issue. Specifically...
both Datatoken.py & DatatokenEnterprise.py support dispense_and_order() and buy_DT_and_order(). Datatoken.py does it in two txs, and DatatokenEnterprise.py in one.
main-flow.md README documents how to use them (and a whole lot more:)

Therefore, shall we close it?

Therefore, shall we close it?

Let's simplify: I'm closing this. Please re-open if you feel otherwise. (I don't expect any issues.)


Statistics for US

Hi, currently US is showing more recovered than confirmed cases. 43847 confirmed cases, 44025 recovered

The folks from Johns Hopkins have changed their data formats which causes some issues. I'll try to look into it asap.

Same issue, but last night I noticed there were 0 recovered.

Johns Hopkins does not provide recovered cases for the US anymore. There's unfortunately not much I can do about that right now. The situation is unsatisfactory for me as well... I might change to a different data source over the weekend. These folks are scraping from various sources:
https://github.com/lazd/coronadatascraper

Again, all wrong numbers are resulting by changes in the source data by Johns Hopkins University. I will have a look at this as soon as I can:
https://github.com/CSSEGISandData/COVID-19/issues/1250

Seems that something is changed now into https://github.com/CSSEGISandData/COVID-19/archive/master.zip
This file is time_series_19-covid-Recovered.csv is missing
I'm getting data/time_series_19-covid-Recovered.csv' does not exist

Yeah I already saw that they changed something again... I'll look into it tonight

Looks like they are reporting recovered cases, see below reported global cases the last 24hrs from time of this post.  This is Home Assistant using the JH API.  See Github here for API code.
https://github.com/home-assistant/core/tree/a3c55b5e96dc1045b85fba6a48aefb93a717031a/homeassistant/components/coronavirus
Additionally, they have updated reporting to more detailed at least for the US.  It now reports state and county, see 2nd image.  Note three additional "admin" panels on left pane where you're able to select State and then County respectively.

I included the US state level data again and removed some weird behavior (cruise ship at 0, 0). I will not include counties as it is too much work for now.
Recovered cases are from data where available and estimated otherwise.

I included the US state level data again and removed some weird behavior (cruise ship at 0, 0). I will not include counties as it is too much work for now.
Recovered cases are from data where available and estimated otherwise.

Thanks! How do you add state level sensors?

I included the US state level data again and removed some weird behavior (cruise ship at 0, 0). I will not include counties as it is too much work for now.
Recovered cases are from data where available and estimated otherwise.

Thanks! How do you add state level sensors?

What do you mean by "state level sensors"?

I included the US state level data again and removed some weird behavior (cruise ship at 0, 0). I will not include counties as it is too much work for now.
Recovered cases are from data where available and estimated otherwise.

Thanks! How do you add state level sensors?

What do you mean by "state level sensors"?

Never mind mixed up to what I was responding to. Please ignore and thank you for all your hard work!


[Urgent] DependencyContext cannot load entry assembly when used in a net46 test.

Description
Trying to do DependencyContext.Load(TheCurrentAssembly) in a net46 test returns null due to core-setup's "is entry assembly check" failing. Ultimately it fails due to Assembly.GetEntryAssembly() returning null when invoked inside of a test. The test runner should ensure GetEntryAssembly works as expected.
Environment
dotnet --info:
.NET Command Line Tools (1.0.0-preview3-004056)

Product Information:
 Version:            1.0.0-preview3-004056
 Commit SHA-1 hash:  ccc4968bc3

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.14393
 OS Platform: Windows
 RID:         win10-x64

Microsoft.NET.Test.Sdk version tested:
15.0.0-preview-20161024-02

So I got back into migrating MVC this week and it looks like it was a different test that was failing than what I had tested above. This issue still holds true but for different reasons.

Desktop deps.json bits are not embedded into dll's anymore therefore this check fails. (By Design)
The test.dll is shadow copied to a temporary location for desktop which ends up breaking the logic here to locate the deps.json's location on disk. (The Problem)

In the end DependencyContext has no way of locating the deps.json file for the test.dll so DependencyContext.Load(TestAssembly) fails. May be able to work around the issue by also shadow copying (or manually copying) the deps.json file.

@NTaylorMullen what is the latest you were able to do?
@codito @Faizan2304 any ideas?

@NTaylorMullen what is the latest you were able to do?

Not sure I follow.

@NTaylorMullen you mentioned that you might be able to work around the issue, so just asking were you able to work around it or is this still blocking you?

@blackdwarf Didn't go down that path yet. I let the test failure live and moved onto the next MVC test pieces to find more issues 😄. I'd imagine manually copying the bits needed next to the shadow copied dll for net46 should work but that's all speculation.

@NTaylorMullen ok. :) Is this blocking you?

After discussions with @Eilon. Yes this is blocking, if you could mark it as so that'd be great 😄

@blackdwarf can we have a label in this repo called "blocking release" and mark this issue with that label? That way we can track it in Core War.
cc @balachir because we'll want to track this in his queries.

@Eilon yup, makes sense. :)

The test.dll is shadow copied to a temporary location for desktop which ends up breaking the logic here to locate the deps.json's location on disk. (The Problem)

Shadow copy is default behavior of xunit adapter. It can be turned off with a configuration file. See attached project for sample.
xunit3.zip
Following test passes with configuration.
        [Fact]
        public void Test1()
        {
            // This passes since testhost.exe executes from assembly directory
            Assert.Equal(Environment.CurrentDirectory, @"D:\tmp\bash\xunit3\bin\Debug\net46");

            // This fails because the assembly seems to run from %temp%
            Assert.Equal(@"D:\tmp\bash\xunit3\bin\Debug\net46\xunit3.dll", typeof(UnitTest1).GetTypeInfo().Assembly.Location);
        }

Closing this issue since shadow copy feature is part of adapter business logic and is configurable. It is not possible to fix it from test platform.


All crawlers should have custom error messages.

Currently all crawlers share a single error message when a request fails
ERROR: BasicCrawler: handleRequestFunction failed, reclaiming failed request back to the list or queue

We should create separate error messages for all three crawlers so users don't get confused.

We could update our log implementation in shared to allow named instances:
const log = new Log('PuppeteerCrawler');
log.info('test message');
// => INFO: PuppeteerCrawler: test message

Then we could add parameter instanceName to all the classes.

I guess this is implemented as well and just forgotten issue, as we have a log prefix now that uses this.constructor.name.


Training Series Endpoints

Added endpoint to find volunteers from training series / incomplete
Description
Checked all the endpoints for what is expected from planning and on trello. Added one new endpoint to find the volunteers working on a certain training series. Most of the set up is finished waiting for data model and schema to be updated before finishing
Type of change
Please delete options that are not relevant.

[x] New feature (non-breaking change which adds functionality)
[x] This change requires a documentation update

Change status

[ ] Complete, tested, ready to review and merge
[ ] Complete, but not tested (may need new tests)
[x] Incomplete/work-in-progress, PR is for discussion/feedback

How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

[ ] Test A
[ ] Test B

Checklist:

[x] My code follows the style guidelines of this project
[x] I have performed a self-review of my own code
[ ] My code has been reviewed by at least one peer
[x] I have commented my code, particularly in hard-to-understand areas
[ ] I have made corresponding changes to the documentation
[x] My changes generate no new warnings
[ ] There are no merge conflicts

Joi schema still has user_id required so when doing a .put request it is required to have a user_id with the request in the req.body. Two solutions one is to remove the required on the user_id or just remove schema validation on the put request. Going to talk to team about this.


I made a mistake when creating a new vue/cli demo

Version
3.6.3
Reproduction link
https://github.com/qq229338869/my-question/blob/master/vue/vue-cli/question-one
Environment info
  System:
    OS: macOS Mojave 10.14.3
    CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  Binaries:
    Node: 10.15.3 - /usr/local/bin/node
    Yarn: Not Found
    npm: 6.4.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 73.0.3683.103
    Firefox: 66.0.3
    Safari: 12.0.3
  npmGlobalPackages:
    @vue/cli: 3.6.3

Steps to reproduce
after install @vue/cli , webpack ,run  vue create my-project
What is expected?
create the vue/cle demo
What is actually happening?
fail
ERROR  command failed: pnpm install --loglevel error --shamefully-flatten

on windows ,i was success but macos.
i want to know "ERROR  command failed: pnpm install --loglevel error --shamefully-flatten"
when install pnpm ,run 'vue create', still fail,

If you are in China, it's very likely the error is caused by the taobao npm registry.
I haven't figured out why but changing the registry from https://registry.npm.taobao.org/ to https://r.cnpmjs.org/ fixed this issue on my machine.

If you are in China, it's very likely the error is caused by the taobao npm registry.
I haven't figured out why but changing the registry from https://registry.npm.taobao.org/ to https://r.cnpmjs.org/ fixed this issue on my machine.

thank you for your answer.
i changed registry,it still doesn`t work.
now ,i create the demo on windows ,then copy it in macos ，it work.
forgive my Chinglish.

@qq229338869
Try edit ~/.vuerc and change the useTaobaoRegistry option to false.
Also, are you sure you have pnpm installed?

Fixed. See https://github.com/cnpm/cnpmjs.org/issues/1458


lspconfig doesn't play nicely with ftplugin

nvim --version: NVIM v0.5.0-dev+1397-gf3bcdeb0c
nvim-lsp version(commit hash): 5ef390d90fbd5f311a967ce708550bab30b79baf
What language server (If the problem is related to a specific language server): N/A
Can you reproduce this behavior on other language server clients (vscode, languageclient-neovim, coc.nvim, etc.): N/A
Can you reproduce this behavior on other language servers offered in the nvim-lspconfig repo? (pyls -> pyright): N/A
Is the problem isolated to a particular language server: N/A
Operating system/version: Debian 11

How to reproduce the problem from neovim startup
Have the following as rust.lua in any ftplugin directory:
require('lspconfig').rust_analyzer.setup({})

Then open a rust file in any project (cargo new lspconfig to make a new one if needed) and call :LspInfo.
Actual behaviour
No client is attached, unless rust analyzer is setup in both ftplugin and after/ftplugin.
Expected behaviour
A client is attached with only one call to setup (or a similar, separate function if needed).
More generally, it would be nice to have a way of setting up lspconfig per filetype in a non-centralized way: it is more idiomatic, requires evaluating less lua at startup and makes splitting a config more natural.
Minimal init.vim or init.lua and code sample
vim.api.nvim_call_function('plug#begin', { vim.fn.stdpath('data') .. '/plugged' })
vim.api.nvim_command([[ Plug 'neovim/nvim-lspconfig' ]])
vim.api.nvim_call_function('plug#end', {})

Health check

Checkhealth result
```
health#lspconfig#check
========================================================================
## Checking language server protocol configuration
  - INFO: rust_analyzer: configuration checked.
```

LSP log

Log file
```
[ START ] 2021-06-12T14:55:34+0200 ] LSP logging initiated
[ INFO ] 2021-06-12T14:55:43+0200 ] ...c/.local/share/neovim/share/nvim/runtime/lua/vim/lsp.lua:1213 ]  "exit_handler"  {}
```

A couple points:

The only supported way to configure lspconfig is by adding it to init.vim/init.lua
Most people will benefit from having a shared on-attach function, so this way is also more concise
"requires evaluating less lua at startup" -> the total time for evaluating a setup call across all language servers in the repo was around 1 ms (combined) last time I checked
multi-file configs are not more idiomatic
The autocommand needs to be registered before the first BufEnter is called, if you run :e on the buffer it should trigger re-attach (and everything should just work)
You should not be replacing your filetype plugin (unless you really mean to), the correct usage would be putting the setup call in after
If you really want this to work, you can probably add require'lspconfig'['rust_analyzer'].manager.try_add_wrapper() in your filetype plugin after the setup call

Thanks for the detailed reply, I appreciate it.

The only supported way to configure lspconfig is by adding it to init.vim/init.lua

Yeah, that's my "issue" here.

Most people will benefit from having a shared on-attach function, so this way is also more concise

Of course, me too, but that's easily shoved into some lua/lspcommon.lua.

"requires evaluating less lua at startup" -> the total time for evaluating a setup call across all language servers in the repo was around 1 ms (combined) last time I checked

Fair enough

multi-file configs are not more idiomatic

How do you suggest handling different file types differently then, shoving raw autocmds in one init file? after/ftplugin exists for a reason and afaik that's precisely it.

If you really want this to work, you can probably add require'lspconfig'['rust_analyzer'].manager.try_add_wrapper() in your filetype plugin after the setup call in after

Brilliant, that works just fine for me, thanks :)

How do you suggest handling different file types differently then, shoving raw autocmds in one init file? after/ftplugin exists for a reason and afaik that's precisely it.

I recommend using on_init/on_attach, since the language server generally will only be started in the filetype that matches the filetypes specified in the setup{} call, but I provided the snippet you needed to use the filetype plugin so I think this point is moot :)
To give more details as to why it was not working for you, the issue is that the filetype plugin is evaluated after the first BufEnter, so it never triggers the autocommand even though the autocommand is mapped, the snippet I gave you manually invokes a function that attaches the current buffer after the filetype plugin is called, avoiding the issue.


Create New File Indexer

Create a file indexer adhering to the new ElasticSearch mapping.
DOD: The indexer creates an ElasticSearch document for each relevant file in the bundle, adhering to the new format (https://docs.google.com/document/d/1OWuPZHQnAGdGK8koJdLbnIZ6TT7F6WonZ6cEKfxsR8U/edit). Associates the samples, processes and protocols to each file respectively. Unit tests included.

A day or two left...

Target complete 5/30.


Remove version: YumiUsb.exFAT version <IP_ADDRESS>

[Automated] It returns code over 400 in all urls
Microsoft Reviewers: Open in CodeFlow

[Policy] Highest Version Remaining


hvplot does not render in code cells, panel widgets

Thanks for contacting us! Please read and follow these instructions carefully, then delete this introductory text to keep your issue easy to read. Note that the issue tracker is NOT the place for usage questions and technical assistance; post those at Discourse instead. Issues without the required information below may be closed immediately.
ALL software version info
(this library, plus any other relevant software, e.g. bokeh, python, notebook, OS, browser, etc)
hvplot 0.9.0
bokeh 3.3.2
panel 1.3.4
holoviews 1.18.1
jupyterlab 4.0.9
Description of expected behavior and the observed behavior
This happened after update of bokeh from 3.3.1. There are two issues:

When the code below is run in code cell, it does not display. The same code works when typed in the associated console.  However, when I close and reopen the notebook, the image is shown in the code cell.
Another problem is that the select widget does not work (when displayed in console): the items can be selected, but the image does not change.

I tried both firefox and chromium browsers. The javascript console log output is shown below.
Complete, minimal, self-contained example code that reproduces the issue
# code goes here between backticks
import panel as pn
import hvplot.pandas  # noqa

from bokeh.sampledata.iris import flowers

flowers.hvplot.bivariate(x='sepal_width', y='sepal_length', width=600,
                         groupby='species')

Stack traceback and/or browser JavaScript console output
Kernel not found, could not register comm target  88e9030be98c4772a287ba219fc9b1c9
30.142e2e0fa2b610ad434f.js?v=142e2e0fa2b610ad434f:1
Kernel not found, could not connect to comm target  8b26b18e4d574fe88e11c2a944906088
jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1
Uncaught Error: Comms are disabled on this kernel connection
    at y.createComm (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1238060)
    at Object.connectToComm (30.142e2e0fa2b610ad434f.js?v=142e2e0fa2b610ad434f:1:9054)
    at JupyterCommManager.get_client_comm (<anonymous>:51:50)
    at d.initialize (panel.min.js:54:833)
    at d.finalize (bokeh-3.3.2.min.js:179:4582)
    at p.decode (bokeh-3.3.2.min.js:212:805)
    at S.from_json (bokeh-3.3.2.min.js:165:6273)
    at t.embed_items_notebook (bokeh-3.3.2.min.js:231:2268)
    at embed_document (<anonymous>:11:17)
    at <anonymous>:40:5

Screenshots or screencasts of the bug in action

[ ] I may be interested in making a pull request to address this

I did more tests. It is not bokeh, there is something going on. I duplicated the code below in two identical notebooks.
import panel as pn
import hvplot.pandas  # noqa

from bokeh.sampledata.iris import flowers

flowers.hvplot.bivariate(x='sepal_width', y='sepal_length', width=600,
                         groupby='species')

I had a case when, after opening both, one of them worked, the other did not display the image (there were several messages Kernel not found, could not connect to comm target in JavaScript console). However, when I changed JupyterLab kernel to a different one, then changed it back, the code started working again. My hunch is an issue with pyviz_comms.

But please, could you make sure that it all works as expected if you install pyviz_comms in the environment that contains JupyterLab?

I did more testing.  My enviroments:
jupyter: bokeh 3.3.2, pyviz_comms 3.3.0, panel 1.3.4
icec: same as above
test: same
test2: bokeh 3.3.1, rest same as above.
I use jupyter to run jupyterlab. The code works in icec and test. When I switch kernels I do see warnings in the java console, but those seem to be harmless:
TypeError: Cannot read properties of undefined (reading 'widget')
    at isReady (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1061486)
    at jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:878686
    at b (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:878780)
    at P.onKernelChanged (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1060643)
    at m (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1656463)
    at Object.l [as emit] (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1656139)
    at a.emit (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1653976)
    at b._onKernelChanged (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:132362)
    at m (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1656463)
    at Object.l [as emit] (jlab_core.a61821d8a2a9c35d7996.js?v=a61821d8a2a9c35d7996:1:1656139)

Failed to fetch ipywidgets through the "jupyter.widget.control" comm channel, fallback to fetching individual model state. Reason: Control comm was closed too early

It does not work in test2, the error is
Panel: ERROR: Unable to run Panel code because Bokeh or Panel library is missing

So, it seems that bokeh versions must match exactly. Is there a section in the documentation that would tell me which components belong to the jupyter environment, and which should go to the client side? I looked at https://docs.bokeh.org/en/latest/docs/first_steps/installation.html and https://panel.holoviz.org/getting_started/installation.html, the scenario of separate environmens is not covered.

Hi @yt87, you should not have to deal with installing client-side versions of Bokeh, the Python and client versions should be the same.
I've been able to reproduce (part of?) your problem, by:

creating a test1 env with bokeh 3.3.2 and a test2 env with bokeh 3.3.1
running JupyterLab from another environment with the latest pyviz_comms version
running the snippet in a new notebook from test1
running the snippet in another notebook from test2

In which case, in the second notebook, the plot isn't rendered at all. @philippjfr do you happen to know if that is a fundamental limitation of Bokeh in JupyterLab, i.e. that there can't be multiple versions of Bokeh loaded over multiple notebooks? Or is this a bug (potentially a very hard one to fix)?
For what it's worth @yt87, Jupyter Notebook (not Lab) doesn't suffer from the same issue, each notebook being in its own browser tab helps avoiding this kind of issue.

In which case, in the second notebook, the plot isn't rendered at all. @philippjfr do you happen to know if that is a fundamental limitation of Bokeh in JupyterLab, i.e. that there can't be multiple versions of Bokeh loaded over multiple notebooks? Or is this a bug (potentially a very hard one to fix)?

In recent versions of Panel I started adding support for loading multiple versions of Bokeh and allowing users to switch between them. If this is not working right, that's to be considered a Panel bug at this point.


Ignore "Wimplicit-fallthrough" warning

@mgonchar Yes, but we have a lot of switches where this warning occur. The another solution is to add [[clang::fallthrough]]; but I think that this is not god idea because instead of:
case MFX_HW_CNL:
case MFX_HW_ICL:
case MFX_HW_ICL_LP:
we will have to write:
case MFX_HW_CNL: [[clang::fallthrough]];
case MFX_HW_ICL: [[clang::fallthrough]];
case MFX_HW_ICL_LP: [[clang::fallthrough]];

@Losev-Ivan as alternative you can mute specific compiler warning for block of code. I don't like the idea of turning this option off. Let's maybe wait for some other opinion. By the way, how many hits of such warning do we have?

@mgonchar approximately 43


Move testing.NewDynamicClientWithInformer to the spoke pkg

...as it's only used there. This will facilitate removal of the helpers/testing module.

/cc skitt Jaanki dfarrell07

/cc skitt Jaanki

/approve

/lgtm


How to Show SpannableString as Progress Text?

@chnouman you can set a new indicator view and change this view you want(include a TEXT with SpannableString  )
seekBar.getIndicator().setContentView(yourView with SpannableString );
more detail you can see demo.apk with part of custom indicator.

@warkiz  thanks a lot I'll check this out.


Bug: Homepage linear-gradient in iphone Safari

The linear gradient isn't properly rendering in ios Safari the way it is when emulating via browser.

Looks like we're using a linear gradient within Franklin to render the curve. This method doesn't yield consistent results on all browsers, especially on Safari mobile. We might need to switch to using SVG, which looks to be what we were using on the AEM version of the homepage (https://author-p65153-e554352.adobeaemcloud.com/content/merative/us/en.html?wcmmode=disabled).


Updating Project Wiki To Address The Status Of PHP-RBAC

PHP-RBAC's Status & Updates - 01-24-15
There have been questions asked, Issues logged, great suggestions/feedback and interest in the status and future of PHP-RBAC, along with interest in shown in helping the project move forward.
First of all, we'd like to thank everyone for their interest.
Second of all, I am in the process of updating the Project Wiki in order to share:

The history of PHP-RBAC
The current status of PHP-RBAC
And our plans regarding the future of PHP-RBAC

Please stay tuned, as I will update this Issue once the Wiki has been updated!
Thanks!

I've added the PHP-RBAC's Status & Updates - 01-24-15 page to the wiki.