omlish 0.0.0.dev469__py3-none-any.whl → 0.0.0.dev471__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- omlish/__about__.py +2 -2
 - omlish/http/all.py +27 -7
 - omlish/http/clients/asyncs.py +8 -8
 - omlish/http/clients/middleware.py +6 -3
 - omlish/http/clients/sync.py +8 -8
 - omlish/http/clients/syncasync.py +43 -0
 - omlish/inject/__init__.py +4 -0
 - omlish/inject/elements.py +17 -0
 - omlish/inject/impl/elements.py +17 -2
 - omlish/inject/impl/injector.py +17 -19
 - omlish/inject/impl/inspect.py +7 -1
 - omlish/inject/impl/maysync.py +3 -4
 - omlish/inject/impl/sync.py +3 -4
 - omlish/inject/injector.py +31 -2
 - omlish/inject/maysync.py +2 -4
 - omlish/inject/sync.py +5 -4
 - omlish/lang/imports/proxy.py +10 -1
 - omlish/term/pager.py +235 -0
 - omlish/term/terminfo.py +935 -0
 - omlish/term/termstate.py +67 -0
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/METADATA +1 -1
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/RECORD +27 -23
 - /omlish/inject/impl/{providers2.py → providersmap.py} +0 -0
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/WHEEL +0 -0
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/entry_points.txt +0 -0
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/licenses/LICENSE +0 -0
 - {omlish-0.0.0.dev469.dist-info → omlish-0.0.0.dev471.dist-info}/top_level.txt +0 -0
 
    
        omlish/__about__.py
    CHANGED
    
    
    
        omlish/http/all.py
    CHANGED
    
    | 
         @@ -7,16 +7,15 @@ with _lang.auto_proxy_init(globals()): 
     | 
|
| 
       7 
7 
     | 
    
         
             
                from .clients.asyncs import (  # noqa
         
     | 
| 
       8 
8 
     | 
    
         
             
                    AsyncStreamHttpResponse,
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                     
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
       12 
     | 
    
         
            -
                     
     | 
| 
      
 10 
     | 
    
         
            +
                    async_close_http_client_response,
         
     | 
| 
      
 11 
     | 
    
         
            +
                    async_closing_http_client_response,
         
     | 
| 
      
 12 
     | 
    
         
            +
                    async_read_http_client_response,
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                    AsyncHttpClient,
         
     | 
| 
       15 
15 
     | 
    
         
             
                )
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
                from .clients.base import (  # noqa
         
     | 
| 
       18 
18 
     | 
    
         
             
                    DEFAULT_ENCODING,
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
19 
     | 
    
         
             
                    is_success_status,
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
21 
     | 
    
         
             
                    HttpRequest,
         
     | 
| 
         @@ -24,8 +23,12 @@ with _lang.auto_proxy_init(globals()): 
     | 
|
| 
       24 
23 
     | 
    
         
             
                    BaseHttpResponse,
         
     | 
| 
       25 
24 
     | 
    
         
             
                    HttpResponse,
         
     | 
| 
       26 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
                    HttpClientContext,
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       27 
28 
     | 
    
         
             
                    HttpClientError,
         
     | 
| 
       28 
29 
     | 
    
         
             
                    HttpStatusError,
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                    BaseHttpClient,
         
     | 
| 
       29 
32 
     | 
    
         
             
                )
         
     | 
| 
       30 
33 
     | 
    
         | 
| 
       31 
34 
     | 
    
         
             
                from .clients.default import (  # noqa
         
     | 
| 
         @@ -42,18 +45,35 @@ with _lang.auto_proxy_init(globals()): 
     | 
|
| 
       42 
45 
     | 
    
         | 
| 
       43 
46 
     | 
    
         
             
                from .clients.httpx import (  # noqa
         
     | 
| 
       44 
47 
     | 
    
         
             
                    HttpxHttpClient,
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    HttpxAsyncHttpClient,
         
     | 
| 
      
 50 
     | 
    
         
            +
                )
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                from .clients.middleware import (  # noqa
         
     | 
| 
      
 53 
     | 
    
         
            +
                    HttpClientMiddleware,
         
     | 
| 
      
 54 
     | 
    
         
            +
                    AbstractMiddlewareHttpClient,
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                    MiddlewareHttpClient,
         
     | 
| 
      
 57 
     | 
    
         
            +
                    MiddlewareAsyncHttpClient,
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                    TooManyRedirectsHttpClientError,
         
     | 
| 
      
 60 
     | 
    
         
            +
                    RedirectHandlingHttpClientMiddleware,
         
     | 
| 
       45 
61 
     | 
    
         
             
                )
         
     | 
| 
       46 
62 
     | 
    
         | 
| 
       47 
63 
     | 
    
         
             
                from .clients.sync import (  # noqa
         
     | 
| 
       48 
64 
     | 
    
         
             
                    StreamHttpResponse,
         
     | 
| 
       49 
65 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                     
     | 
| 
       51 
     | 
    
         
            -
                     
     | 
| 
       52 
     | 
    
         
            -
                     
     | 
| 
      
 66 
     | 
    
         
            +
                    close_http_client_response,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    closing_http_client_response,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    read_http_client_response,
         
     | 
| 
       53 
69 
     | 
    
         | 
| 
       54 
70 
     | 
    
         
             
                    HttpClient,
         
     | 
| 
       55 
71 
     | 
    
         
             
                )
         
     | 
| 
       56 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
                from .clients.syncasync import (  # noqa
         
     | 
| 
      
 74 
     | 
    
         
            +
                    SyncAsyncHttpClient,
         
     | 
| 
      
 75 
     | 
    
         
            +
                )
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       57 
77 
     | 
    
         
             
                from .clients.urllib import (  # noqa
         
     | 
| 
       58 
78 
     | 
    
         
             
                    UrllibHttpClient,
         
     | 
| 
       59 
79 
     | 
    
         
             
                )
         
     | 
    
        omlish/http/clients/asyncs.py
    CHANGED
    
    | 
         @@ -57,13 +57,13 @@ class AsyncStreamHttpResponse(BaseHttpResponse): 
     | 
|
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                async def close(self) -> None:
         
     | 
| 
       59 
59 
     | 
    
         
             
                    if (c := self._closer) is not None:
         
     | 
| 
       60 
     | 
    
         
            -
                        await c()
         
     | 
| 
      
 60 
     | 
    
         
            +
                        await c()  # noqa
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
63 
     | 
    
         
             
            #
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
            async def  
     | 
| 
      
 66 
     | 
    
         
            +
            async def async_close_http_client_response(resp: BaseHttpResponse) -> None:
         
     | 
| 
       67 
67 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       68 
68 
     | 
    
         
             
                    pass
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
         @@ -75,7 +75,7 @@ async def async_close_response(resp: BaseHttpResponse) -> None: 
     | 
|
| 
       75 
75 
     | 
    
         | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
            @contextlib.asynccontextmanager
         
     | 
| 
       78 
     | 
    
         
            -
            async def  
     | 
| 
      
 78 
     | 
    
         
            +
            async def async_closing_http_client_response(resp: BaseHttpResponseT) -> ta.AsyncGenerator[BaseHttpResponseT, None]:
         
     | 
| 
       79 
79 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       80 
80 
     | 
    
         
             
                    yield resp
         
     | 
| 
       81 
81 
     | 
    
         
             
                    return
         
     | 
| 
         @@ -90,7 +90,7 @@ async def async_closing_response(resp: BaseHttpResponseT) -> ta.AsyncGenerator[B 
     | 
|
| 
       90 
90 
     | 
    
         
             
                    raise TypeError(resp)
         
     | 
| 
       91 
91 
     | 
    
         | 
| 
       92 
92 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
            async def  
     | 
| 
      
 93 
     | 
    
         
            +
            async def async_read_http_client_response(resp: BaseHttpResponse) -> HttpResponse:
         
     | 
| 
       94 
94 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       95 
95 
     | 
    
         
             
                    return resp
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
         @@ -121,12 +121,12 @@ class AsyncHttpClient(BaseHttpClient, Abstract): 
     | 
|
| 
       121 
121 
     | 
    
         
             
                        context: ta.Optional[HttpClientContext] = None,
         
     | 
| 
       122 
122 
     | 
    
         
             
                        check: bool = False,
         
     | 
| 
       123 
123 
     | 
    
         
             
                ) -> HttpResponse:
         
     | 
| 
       124 
     | 
    
         
            -
                    async with  
     | 
| 
      
 124 
     | 
    
         
            +
                    async with async_closing_http_client_response(await self.stream_request(
         
     | 
| 
       125 
125 
     | 
    
         
             
                            req,
         
     | 
| 
       126 
126 
     | 
    
         
             
                            context=context,
         
     | 
| 
       127 
127 
     | 
    
         
             
                            check=check,
         
     | 
| 
       128 
128 
     | 
    
         
             
                    )) as resp:
         
     | 
| 
       129 
     | 
    
         
            -
                        return await  
     | 
| 
      
 129 
     | 
    
         
            +
                        return await async_read_http_client_response(resp)
         
     | 
| 
       130 
130 
     | 
    
         | 
| 
       131 
131 
     | 
    
         
             
                async def stream_request(
         
     | 
| 
       132 
132 
     | 
    
         
             
                        self,
         
     | 
| 
         @@ -146,10 +146,10 @@ class AsyncHttpClient(BaseHttpClient, Abstract): 
     | 
|
| 
       146 
146 
     | 
    
         
             
                                cause = resp.underlying
         
     | 
| 
       147 
147 
     | 
    
         
             
                            else:
         
     | 
| 
       148 
148 
     | 
    
         
             
                                cause = None
         
     | 
| 
       149 
     | 
    
         
            -
                            raise HttpStatusError(await  
     | 
| 
      
 149 
     | 
    
         
            +
                            raise HttpStatusError(await async_read_http_client_response(resp)) from cause  # noqa
         
     | 
| 
       150 
150 
     | 
    
         | 
| 
       151 
151 
     | 
    
         
             
                    except Exception:
         
     | 
| 
       152 
     | 
    
         
            -
                        await  
     | 
| 
      
 152 
     | 
    
         
            +
                        await async_close_http_client_response(resp)
         
     | 
| 
       153 
153 
     | 
    
         
             
                        raise
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
       155 
155 
     | 
    
         
             
                    return resp
         
     | 
| 
         @@ -23,7 +23,7 @@ from .base import HttpClientError 
     | 
|
| 
       23 
23 
     | 
    
         
             
            from .base import HttpRequest
         
     | 
| 
       24 
24 
     | 
    
         
             
            from .sync import HttpClient
         
     | 
| 
       25 
25 
     | 
    
         
             
            from .sync import StreamHttpResponse
         
     | 
| 
       26 
     | 
    
         
            -
            from .sync import  
     | 
| 
      
 26 
     | 
    
         
            +
            from .sync import close_http_client_response
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            BaseHttpClientT = ta.TypeVar('BaseHttpClientT', bound=BaseHttpClient)
         
     | 
| 
         @@ -84,6 +84,9 @@ class AbstractMiddlewareHttpClient(Abstract, ta.Generic[BaseHttpClientT]): 
     | 
|
| 
       84 
84 
     | 
    
         
             
                    return resp
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
       86 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
            #
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
       87 
90 
     | 
    
         
             
            class MiddlewareHttpClient(AbstractMiddlewareHttpClient[HttpClient], HttpClient):
         
     | 
| 
       88 
91 
     | 
    
         
             
                def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> StreamHttpResponse:
         
     | 
| 
       89 
92 
     | 
    
         
             
                    while True:
         
     | 
| 
         @@ -95,7 +98,7 @@ class MiddlewareHttpClient(AbstractMiddlewareHttpClient[HttpClient], HttpClient) 
     | 
|
| 
       95 
98 
     | 
    
         
             
                            out = self._process_response(ctx, req, resp)
         
     | 
| 
       96 
99 
     | 
    
         | 
| 
       97 
100 
     | 
    
         
             
                            if isinstance(out, HttpRequest):
         
     | 
| 
       98 
     | 
    
         
            -
                                 
     | 
| 
      
 101 
     | 
    
         
            +
                                close_http_client_response(resp)
         
     | 
| 
       99 
102 
     | 
    
         
             
                                req = out
         
     | 
| 
       100 
103 
     | 
    
         
             
                                continue
         
     | 
| 
       101 
104 
     | 
    
         | 
| 
         @@ -106,7 +109,7 @@ class MiddlewareHttpClient(AbstractMiddlewareHttpClient[HttpClient], HttpClient) 
     | 
|
| 
       106 
109 
     | 
    
         
             
                                raise TypeError(out)  # noqa
         
     | 
| 
       107 
110 
     | 
    
         | 
| 
       108 
111 
     | 
    
         
             
                        except Exception:
         
     | 
| 
       109 
     | 
    
         
            -
                             
     | 
| 
      
 112 
     | 
    
         
            +
                            close_http_client_response(resp)
         
     | 
| 
       110 
113 
     | 
    
         
             
                            raise
         
     | 
| 
       111 
114 
     | 
    
         | 
| 
       112 
115 
     | 
    
         
             
                    raise RuntimeError
         
     | 
    
        omlish/http/clients/sync.py
    CHANGED
    
    | 
         @@ -57,13 +57,13 @@ class StreamHttpResponse(BaseHttpResponse): 
     | 
|
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                def close(self) -> None:
         
     | 
| 
       59 
59 
     | 
    
         
             
                    if (c := self._closer) is not None:
         
     | 
| 
       60 
     | 
    
         
            -
                        c()
         
     | 
| 
      
 60 
     | 
    
         
            +
                        c()  # noqa
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
63 
     | 
    
         
             
            #
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
            def  
     | 
| 
      
 66 
     | 
    
         
            +
            def close_http_client_response(resp: BaseHttpResponse) -> None:
         
     | 
| 
       67 
67 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       68 
68 
     | 
    
         
             
                    pass
         
     | 
| 
       69 
69 
     | 
    
         | 
| 
         @@ -75,7 +75,7 @@ def close_response(resp: BaseHttpResponse) -> None: 
     | 
|
| 
       75 
75 
     | 
    
         | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
            @contextlib.contextmanager
         
     | 
| 
       78 
     | 
    
         
            -
            def  
     | 
| 
      
 78 
     | 
    
         
            +
            def closing_http_client_response(resp: BaseHttpResponseT) -> ta.Iterator[BaseHttpResponseT]:
         
     | 
| 
       79 
79 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       80 
80 
     | 
    
         
             
                    yield resp
         
     | 
| 
       81 
81 
     | 
    
         
             
                    return
         
     | 
| 
         @@ -88,7 +88,7 @@ def closing_response(resp: BaseHttpResponseT) -> ta.Iterator[BaseHttpResponseT]: 
     | 
|
| 
       88 
88 
     | 
    
         
             
                    raise TypeError(resp)
         
     | 
| 
       89 
89 
     | 
    
         | 
| 
       90 
90 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
            def  
     | 
| 
      
 91 
     | 
    
         
            +
            def read_http_client_response(resp: BaseHttpResponse) -> HttpResponse:
         
     | 
| 
       92 
92 
     | 
    
         
             
                if isinstance(resp, HttpResponse):
         
     | 
| 
       93 
93 
     | 
    
         
             
                    return resp
         
     | 
| 
       94 
94 
     | 
    
         | 
| 
         @@ -119,12 +119,12 @@ class HttpClient(BaseHttpClient, Abstract): 
     | 
|
| 
       119 
119 
     | 
    
         
             
                        context: ta.Optional[HttpClientContext] = None,
         
     | 
| 
       120 
120 
     | 
    
         
             
                        check: bool = False,
         
     | 
| 
       121 
121 
     | 
    
         
             
                ) -> HttpResponse:
         
     | 
| 
       122 
     | 
    
         
            -
                    with  
     | 
| 
      
 122 
     | 
    
         
            +
                    with closing_http_client_response(self.stream_request(
         
     | 
| 
       123 
123 
     | 
    
         
             
                            req,
         
     | 
| 
       124 
124 
     | 
    
         
             
                            context=context,
         
     | 
| 
       125 
125 
     | 
    
         
             
                            check=check,
         
     | 
| 
       126 
126 
     | 
    
         
             
                    )) as resp:
         
     | 
| 
       127 
     | 
    
         
            -
                        return  
     | 
| 
      
 127 
     | 
    
         
            +
                        return read_http_client_response(resp)
         
     | 
| 
       128 
128 
     | 
    
         | 
| 
       129 
129 
     | 
    
         
             
                def stream_request(
         
     | 
| 
       130 
130 
     | 
    
         
             
                        self,
         
     | 
| 
         @@ -144,10 +144,10 @@ class HttpClient(BaseHttpClient, Abstract): 
     | 
|
| 
       144 
144 
     | 
    
         
             
                                cause = resp.underlying
         
     | 
| 
       145 
145 
     | 
    
         
             
                            else:
         
     | 
| 
       146 
146 
     | 
    
         
             
                                cause = None
         
     | 
| 
       147 
     | 
    
         
            -
                            raise HttpStatusError( 
     | 
| 
      
 147 
     | 
    
         
            +
                            raise HttpStatusError(read_http_client_response(resp)) from cause  # noqa
         
     | 
| 
       148 
148 
     | 
    
         | 
| 
       149 
149 
     | 
    
         
             
                    except Exception:
         
     | 
| 
       150 
     | 
    
         
            -
                         
     | 
| 
      
 150 
     | 
    
         
            +
                        close_http_client_response(resp)
         
     | 
| 
       151 
151 
     | 
    
         
             
                        raise
         
     | 
| 
       152 
152 
     | 
    
         | 
| 
       153 
153 
     | 
    
         
             
                    return resp
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # ruff: noqa: UP043 UP045
         
     | 
| 
      
 2 
     | 
    
         
            +
            # @omlish-lite
         
     | 
| 
      
 3 
     | 
    
         
            +
            import dataclasses as dc
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            from .asyncs import AsyncHttpClient
         
     | 
| 
      
 6 
     | 
    
         
            +
            from .asyncs import AsyncStreamHttpResponse
         
     | 
| 
      
 7 
     | 
    
         
            +
            from .base import HttpClientContext
         
     | 
| 
      
 8 
     | 
    
         
            +
            from .base import HttpRequest
         
     | 
| 
      
 9 
     | 
    
         
            +
            from .sync import HttpClient
         
     | 
| 
      
 10 
     | 
    
         
            +
            from .sync import StreamHttpResponse
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            ##
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            class SyncAsyncHttpClient(AsyncHttpClient):
         
     | 
| 
      
 17 
     | 
    
         
            +
                def __init__(self, client: HttpClient) -> None:
         
     | 
| 
      
 18 
     | 
    
         
            +
                    super().__init__()
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    self._client = client
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                @dc.dataclass(frozen=True)
         
     | 
| 
      
 23 
     | 
    
         
            +
                class _StreamAdapter:
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ul: StreamHttpResponse
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    async def read1(self, /, n: int = -1) -> bytes:
         
     | 
| 
      
 27 
     | 
    
         
            +
                        return self.ul.stream.read1(n)
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    async def close(self) -> None:
         
     | 
| 
      
 30 
     | 
    
         
            +
                        self.ul.close()
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                async def _stream_request(self, ctx: HttpClientContext, req: HttpRequest) -> AsyncStreamHttpResponse:
         
     | 
| 
      
 33 
     | 
    
         
            +
                    resp = self._client.stream_request(req, context=ctx)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    return AsyncStreamHttpResponse(
         
     | 
| 
      
 35 
     | 
    
         
            +
                        status=resp.status,
         
     | 
| 
      
 36 
     | 
    
         
            +
                        headers=resp.headers,
         
     | 
| 
      
 37 
     | 
    
         
            +
                        request=req,
         
     | 
| 
      
 38 
     | 
    
         
            +
                        underlying=resp,
         
     | 
| 
      
 39 
     | 
    
         
            +
                        **(dict(  # type: ignore
         
     | 
| 
      
 40 
     | 
    
         
            +
                            stream=(adapter := self._StreamAdapter(resp)),
         
     | 
| 
      
 41 
     | 
    
         
            +
                            _closer=adapter.close,
         
     | 
| 
      
 42 
     | 
    
         
            +
                        ) if resp.has_data else {}),
         
     | 
| 
      
 43 
     | 
    
         
            +
                    )
         
     | 
    
        omlish/inject/__init__.py
    CHANGED
    
    
    
        omlish/inject/elements.py
    CHANGED
    
    | 
         @@ -6,6 +6,12 @@ from .. import lang 
     | 
|
| 
       6 
6 
     | 
    
         
             
            from .impl.origins import HasOriginsImpl
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
            if ta.TYPE_CHECKING:
         
     | 
| 
      
 10 
     | 
    
         
            +
                from .impl import elements as _elements
         
     | 
| 
      
 11 
     | 
    
         
            +
            else:
         
     | 
| 
      
 12 
     | 
    
         
            +
                _elements = lang.proxy_import('.impl.elements', __package__)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       9 
15 
     | 
    
         
             
            ##
         
     | 
| 
       10 
16 
     | 
    
         | 
| 
       11 
17 
     | 
    
         | 
| 
         @@ -74,3 +80,14 @@ def iter_elements(*args: Elemental) -> ta.Iterator[Element]: 
     | 
|
| 
       74 
80 
     | 
    
         
             
                        yield from a
         
     | 
| 
       75 
81 
     | 
    
         
             
                    else:
         
     | 
| 
       76 
82 
     | 
    
         
             
                        raise TypeError(a)
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            ##
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            class CollectedElements(lang.PackageSealed, lang.Abstract):
         
     | 
| 
      
 89 
     | 
    
         
            +
                pass
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            def collect_elements(es: Elements | CollectedElements) -> CollectedElements:
         
     | 
| 
      
 93 
     | 
    
         
            +
                return _elements.collect_elements(es)
         
     | 
    
        omlish/inject/impl/elements.py
    CHANGED
    
    | 
         @@ -27,6 +27,7 @@ from ... import collections as col 
     | 
|
| 
       27 
27 
     | 
    
         
             
            from ... import lang
         
     | 
| 
       28 
28 
     | 
    
         
             
            from ..bindings import Binding
         
     | 
| 
       29 
29 
     | 
    
         
             
            from ..eagers import Eager
         
     | 
| 
      
 30 
     | 
    
         
            +
            from ..elements import CollectedElements
         
     | 
| 
       30 
31 
     | 
    
         
             
            from ..elements import Element
         
     | 
| 
       31 
32 
     | 
    
         
             
            from ..elements import Elements
         
     | 
| 
       32 
33 
     | 
    
         
             
            from ..errors import ConflictingKeyError
         
     | 
| 
         @@ -47,7 +48,7 @@ from .multis import make_multi_provider_impl 
     | 
|
| 
       47 
48 
     | 
    
         
             
            from .origins import Origins
         
     | 
| 
       48 
49 
     | 
    
         
             
            from .origins import set_origins
         
     | 
| 
       49 
50 
     | 
    
         
             
            from .providers import ProviderImpl
         
     | 
| 
       50 
     | 
    
         
            -
            from . 
     | 
| 
      
 51 
     | 
    
         
            +
            from .providersmap import make_provider_impl
         
     | 
| 
       51 
52 
     | 
    
         
             
            from .scopes import make_scope_impl
         
     | 
| 
       52 
53 
     | 
    
         | 
| 
       53 
54 
     | 
    
         | 
| 
         @@ -80,7 +81,7 @@ _NON_BINDING_ELEMENT_TYPES: tuple[type[Element], ...] = ( 
     | 
|
| 
       80 
81 
     | 
    
         
             
            )
         
     | 
| 
       81 
82 
     | 
    
         | 
| 
       82 
83 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
            class ElementCollection(lang.Final):
         
     | 
| 
      
 84 
     | 
    
         
            +
            class ElementCollection(CollectedElements, lang.Final):
         
     | 
| 
       84 
85 
     | 
    
         
             
                def __init__(self, es: Elements) -> None:
         
     | 
| 
       85 
86 
     | 
    
         
             
                    super().__init__()
         
     | 
| 
       86 
87 
     | 
    
         | 
| 
         @@ -208,6 +209,10 @@ class ElementCollection(lang.Final): 
     | 
|
| 
       208 
209 
     | 
    
         | 
| 
       209 
210 
     | 
    
         
             
                ##
         
     | 
| 
       210 
211 
     | 
    
         | 
| 
      
 212 
     | 
    
         
            +
                @lang.cached_function
         
     | 
| 
      
 213 
     | 
    
         
            +
                def scope_binding_scopes(self) -> ta.Sequence[Scope]:
         
     | 
| 
      
 214 
     | 
    
         
            +
                    return [sb.scope for sb in self.elements_of_type(ScopeBinding)]
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
       211 
216 
     | 
    
         
             
                @lang.cached_function
         
     | 
| 
       212 
217 
     | 
    
         
             
                def eager_keys_by_scope(self) -> ta.Mapping[Scope, ta.Sequence[Key]]:
         
     | 
| 
       213 
218 
     | 
    
         
             
                    bim = self.binding_impl_map()
         
     | 
| 
         @@ -216,3 +221,13 @@ class ElementCollection(lang.Final): 
     | 
|
| 
       216 
221 
     | 
    
         
             
                        bi = bim[e.key]
         
     | 
| 
       217 
222 
     | 
    
         
             
                        ret.setdefault(bi.scope, []).append(e.key)
         
     | 
| 
       218 
223 
     | 
    
         
             
                    return ret
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
             
     | 
| 
      
 226 
     | 
    
         
            +
            ##
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
            def collect_elements(es: Elements | CollectedElements) -> ElementCollection:
         
     | 
| 
      
 230 
     | 
    
         
            +
                if isinstance(es, CollectedElements):
         
     | 
| 
      
 231 
     | 
    
         
            +
                    return check.isinstance(es, ElementCollection)
         
     | 
| 
      
 232 
     | 
    
         
            +
                else:
         
     | 
| 
      
 233 
     | 
    
         
            +
                    return ElementCollection(es)
         
     | 
    
        omlish/inject/impl/injector.py
    CHANGED
    
    | 
         @@ -2,14 +2,12 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
            TODO:
         
     | 
| 
       3 
3 
     | 
    
         
             
             - ** can currently bind in a child/private scope shadowing an external parent binding **
         
     | 
| 
       4 
4 
     | 
    
         
             
             - better source tracking
         
     | 
| 
       5 
     | 
    
         
            -
             - cache/export ElementCollections lol
         
     | 
| 
       6 
5 
     | 
    
         
             
             - scope bindings, auto in root
         
     | 
| 
       7 
6 
     | 
    
         
             
             - injector-internal / blacklisted bindings (Injector itself, default scopes) without rebuilding ElementCollection
         
     | 
| 
       8 
7 
     | 
    
         
             
             - config - proxies, impl select, etc
         
     | 
| 
       9 
8 
     | 
    
         
             
              - config is probably shared with ElementCollection... but not 'bound', must be shared everywhere
         
     | 
| 
       10 
9 
     | 
    
         
             
              - InjectorRoot object?
         
     | 
| 
       11 
10 
     | 
    
         
             
             - ** eagers in any scope, on scope init/open
         
     | 
| 
       12 
     | 
    
         
            -
             - injection listeners
         
     | 
| 
       13 
11 
     | 
    
         
             
             - unions - raise on ambiguous - usecase: sql.AsyncEngineLike
         
     | 
| 
       14 
12 
     | 
    
         
             
             - multiple live request scopes on single injector - use private injectors?
         
     | 
| 
       15 
13 
     | 
    
         
             
             - more listeners - UnboundKeyListener
         
     | 
| 
         @@ -24,7 +22,7 @@ import weakref 
     | 
|
| 
       24 
22 
     | 
    
         
             
            from ... import check
         
     | 
| 
       25 
23 
     | 
    
         
             
            from ... import lang
         
     | 
| 
       26 
24 
     | 
    
         
             
            from ...logs import all as logs
         
     | 
| 
       27 
     | 
    
         
            -
            from ..elements import  
     | 
| 
      
 25 
     | 
    
         
            +
            from ..elements import CollectedElements
         
     | 
| 
       28 
26 
     | 
    
         
             
            from ..errors import CyclicDependencyError
         
     | 
| 
       29 
27 
     | 
    
         
             
            from ..errors import UnboundKeyError
         
     | 
| 
       30 
28 
     | 
    
         
             
            from ..injector import AsyncInjector
         
     | 
| 
         @@ -33,7 +31,6 @@ from ..keys import Key 
     | 
|
| 
       33 
31 
     | 
    
         
             
            from ..keys import as_key
         
     | 
| 
       34 
32 
     | 
    
         
             
            from ..listeners import ProvisionListener
         
     | 
| 
       35 
33 
     | 
    
         
             
            from ..listeners import ProvisionListenerBinding
         
     | 
| 
       36 
     | 
    
         
            -
            from ..scopes import ScopeBinding
         
     | 
| 
       37 
34 
     | 
    
         
             
            from ..scopes import Singleton
         
     | 
| 
       38 
35 
     | 
    
         
             
            from ..scopes import ThreadScope
         
     | 
| 
       39 
36 
     | 
    
         
             
            from ..types import Scope
         
     | 
| 
         @@ -61,14 +58,12 @@ DEFAULT_SCOPES: list[Scope] = [ 
     | 
|
| 
       61 
58 
     | 
    
         
             
            class AsyncInjectorImpl(AsyncInjector, lang.Final):
         
     | 
| 
       62 
59 
     | 
    
         
             
                def __init__(
         
     | 
| 
       63 
60 
     | 
    
         
             
                        self,
         
     | 
| 
       64 
     | 
    
         
            -
                        ec:  
     | 
| 
      
 61 
     | 
    
         
            +
                        ec: CollectedElements,
         
     | 
| 
       65 
62 
     | 
    
         
             
                        p: ta.Optional['AsyncInjectorImpl'] = None,
         
     | 
| 
       66 
63 
     | 
    
         
             
                        *,
         
     | 
| 
       67 
64 
     | 
    
         
             
                        internal_consts: dict[Key, ta.Any] | None = None,
         
     | 
| 
       68 
65 
     | 
    
         
             
                ) -> None:
         
     | 
| 
       69 
     | 
    
         
            -
                     
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
                    self._ec = check.isinstance(ec, ElementCollection)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    self._ec = (ec := check.isinstance(ec, ElementCollection))
         
     | 
| 
       72 
67 
     | 
    
         
             
                    self._p: AsyncInjectorImpl | None = check.isinstance(p, (AsyncInjectorImpl, None))
         
     | 
| 
       73 
68 
     | 
    
         | 
| 
       74 
69 
     | 
    
         
             
                    self._internal_consts: dict[Key, ta.Any] = {
         
     | 
| 
         @@ -77,28 +72,31 @@ class AsyncInjectorImpl(AsyncInjector, lang.Final): 
     | 
|
| 
       77 
72 
     | 
    
         
             
                    }
         
     | 
| 
       78 
73 
     | 
    
         | 
| 
       79 
74 
     | 
    
         
             
                    self._bim = ec.binding_impl_map()
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
       80 
76 
     | 
    
         
             
                    self._ekbs = ec.eager_keys_by_scope()
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
       81 
78 
     | 
    
         
             
                    self._pls: tuple[ProvisionListener, ...] = tuple(
         
     | 
| 
       82 
79 
     | 
    
         
             
                        b.listener  # type: ignore[attr-defined]
         
     | 
| 
       83 
80 
     | 
    
         
             
                        for b in itertools.chain(
         
     | 
| 
       84 
81 
     | 
    
         
             
                            ec.elements_of_type(ProvisionListenerBinding),
         
     | 
| 
       85 
     | 
    
         
            -
                             
     | 
| 
      
 82 
     | 
    
         
            +
                            p._pls if p is not None else (),  # noqa
         
     | 
| 
       86 
83 
     | 
    
         
             
                        )
         
     | 
| 
       87 
84 
     | 
    
         
             
                    )
         
     | 
| 
       88 
85 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
                    self._cs: weakref.WeakSet[AsyncInjectorImpl] | None = None  # noqa
         
     | 
| 
       90 
86 
     | 
    
         
             
                    self._root: AsyncInjectorImpl = p._root if p is not None else self  # noqa
         
     | 
| 
       91 
87 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                    self.__cur_req: AsyncInjectorImpl._Request | None = None
         
     | 
| 
       93 
     | 
    
         
            -
             
     | 
| 
       94 
     | 
    
         
            -
                    ss = [
         
     | 
| 
       95 
     | 
    
         
            -
                        *DEFAULT_SCOPES,
         
     | 
| 
       96 
     | 
    
         
            -
                        *[sb.scope for sb in ec.elements_of_type(ScopeBinding)],
         
     | 
| 
       97 
     | 
    
         
            -
                    ]
         
     | 
| 
       98 
88 
     | 
    
         
             
                    self._scopes: dict[Scope, ScopeImpl] = {
         
     | 
| 
       99 
     | 
    
         
            -
                        s: make_scope_impl(s) 
     | 
| 
      
 89 
     | 
    
         
            +
                        s: make_scope_impl(s)
         
     | 
| 
      
 90 
     | 
    
         
            +
                        for s in itertools.chain(
         
     | 
| 
      
 91 
     | 
    
         
            +
                            DEFAULT_SCOPES,
         
     | 
| 
      
 92 
     | 
    
         
            +
                            ec.scope_binding_scopes(),
         
     | 
| 
      
 93 
     | 
    
         
            +
                        )
         
     | 
| 
       100 
94 
     | 
    
         
             
                    }
         
     | 
| 
       101 
95 
     | 
    
         | 
| 
      
 96 
     | 
    
         
            +
                _cs: weakref.WeakSet['AsyncInjectorImpl'] | None = None  # noqa
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                __cur_req: ta.Optional['AsyncInjectorImpl._Request'] = None
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
       102 
100 
     | 
    
         
             
                #
         
     | 
| 
       103 
101 
     | 
    
         | 
| 
       104 
102 
     | 
    
         
             
                _has_run_init: bool = False
         
     | 
| 
         @@ -259,7 +257,7 @@ class AsyncInjectorImpl(AsyncInjector, lang.Final): 
     | 
|
| 
       259 
257 
     | 
    
         
             
                    return obj(**kws)
         
     | 
| 
       260 
258 
     | 
    
         | 
| 
       261 
259 
     | 
    
         | 
| 
       262 
     | 
    
         
            -
            async def create_async_injector( 
     | 
| 
       263 
     | 
    
         
            -
                i = AsyncInjectorImpl( 
     | 
| 
      
 260 
     | 
    
         
            +
            async def create_async_injector(ce: CollectedElements) -> AsyncInjector:
         
     | 
| 
      
 261 
     | 
    
         
            +
                i = AsyncInjectorImpl(ce)
         
     | 
| 
       264 
262 
     | 
    
         
             
                await i._init()  # noqa
         
     | 
| 
       265 
263 
     | 
    
         
             
                return i
         
     | 
    
        omlish/inject/impl/inspect.py
    CHANGED
    
    | 
         @@ -75,6 +75,7 @@ def build_kwargs_target( 
     | 
|
| 
       75 
75 
     | 
    
         
             
                    skip_args: int = 0,
         
     | 
| 
       76 
76 
     | 
    
         
             
                    skip_kwargs: ta.Iterable[str] | None = None,
         
     | 
| 
       77 
77 
     | 
    
         
             
                    raw_optional: bool = False,
         
     | 
| 
      
 78 
     | 
    
         
            +
                    non_strict: bool = False,
         
     | 
| 
       78 
79 
     | 
    
         
             
            ) -> KwargsTarget:
         
     | 
| 
       79 
80 
     | 
    
         
             
                if isinstance(obj, KwargsTarget):
         
     | 
| 
       80 
81 
     | 
    
         
             
                    return obj
         
     | 
| 
         @@ -93,11 +94,15 @@ def build_kwargs_target( 
     | 
|
| 
       93 
94 
     | 
    
         
             
                        continue
         
     | 
| 
       94 
95 
     | 
    
         | 
| 
       95 
96 
     | 
    
         
             
                    if p.annotation is inspect.Signature.empty:
         
     | 
| 
      
 97 
     | 
    
         
            +
                        if non_strict:
         
     | 
| 
      
 98 
     | 
    
         
            +
                            continue
         
     | 
| 
       96 
99 
     | 
    
         
             
                        if p.default is not inspect.Parameter.empty:
         
     | 
| 
       97 
100 
     | 
    
         
             
                            raise KeyError(f'{obj}, {p.name}')
         
     | 
| 
       98 
101 
     | 
    
         
             
                        continue
         
     | 
| 
       99 
102 
     | 
    
         | 
| 
       100 
103 
     | 
    
         
             
                    if p.kind not in (inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.KEYWORD_ONLY):
         
     | 
| 
      
 104 
     | 
    
         
            +
                        if non_strict:
         
     | 
| 
      
 105 
     | 
    
         
            +
                            continue
         
     | 
| 
       101 
106 
     | 
    
         
             
                        raise TypeError(sig)
         
     | 
| 
       102 
107 
     | 
    
         | 
| 
       103 
108 
     | 
    
         
             
                    ann = p.annotation
         
     | 
| 
         @@ -122,7 +127,8 @@ def build_kwargs_target( 
     | 
|
| 
       122 
127 
     | 
    
         
             
                        k = dc.replace(k, tag=pt)
         
     | 
| 
       123 
128 
     | 
    
         | 
| 
       124 
129 
     | 
    
         
             
                    if k in seen:
         
     | 
| 
       125 
     | 
    
         
            -
                         
     | 
| 
      
 130 
     | 
    
         
            +
                        if not non_strict:
         
     | 
| 
      
 131 
     | 
    
         
            +
                            raise ConflictingKeyError(k)
         
     | 
| 
       126 
132 
     | 
    
         
             
                    seen.add(k)
         
     | 
| 
       127 
133 
     | 
    
         | 
| 
       128 
134 
     | 
    
         
             
                    kws.append(Kwarg(
         
     | 
    
        omlish/inject/impl/maysync.py
    CHANGED
    
    | 
         @@ -1,13 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import typing as ta
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            from ... import lang
         
     | 
| 
       4 
     | 
    
         
            -
            from ..elements import  
     | 
| 
      
 4 
     | 
    
         
            +
            from ..elements import CollectedElements
         
     | 
| 
       5 
5 
     | 
    
         
             
            from ..injector import AsyncInjector
         
     | 
| 
       6 
6 
     | 
    
         
             
            from ..inspect import KwargsTarget
         
     | 
| 
       7 
7 
     | 
    
         
             
            from ..keys import Key
         
     | 
| 
       8 
8 
     | 
    
         
             
            from ..maysync import MaysyncInjector
         
     | 
| 
       9 
9 
     | 
    
         
             
            from ..sync import Injector
         
     | 
| 
       10 
     | 
    
         
            -
            from .elements import ElementCollection
         
     | 
| 
       11 
10 
     | 
    
         
             
            from .injector import AsyncInjectorImpl
         
     | 
| 
       12 
11 
     | 
    
         | 
| 
       13 
12 
     | 
    
         | 
| 
         @@ -30,10 +29,10 @@ class MaysyncInjectorImpl(MaysyncInjector, lang.Final): 
     | 
|
| 
       30 
29 
     | 
    
         
             
                    return lang.run_maysync(self._ai.inject(obj))
         
     | 
| 
       31 
30 
     | 
    
         | 
| 
       32 
31 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
            def create_maysync_injector( 
     | 
| 
      
 32 
     | 
    
         
            +
            def create_maysync_injector(ce: CollectedElements) -> MaysyncInjector:
         
     | 
| 
       34 
33 
     | 
    
         
             
                si = MaysyncInjectorImpl()
         
     | 
| 
       35 
34 
     | 
    
         
             
                ai = AsyncInjectorImpl(
         
     | 
| 
       36 
     | 
    
         
            -
                     
     | 
| 
      
 35 
     | 
    
         
            +
                    ce,
         
     | 
| 
       37 
36 
     | 
    
         
             
                    internal_consts={
         
     | 
| 
       38 
37 
     | 
    
         
             
                        Key(MaysyncInjector): si,
         
     | 
| 
       39 
38 
     | 
    
         
             
                        Key(Injector): si,
         
     | 
    
        omlish/inject/impl/sync.py
    CHANGED
    
    | 
         @@ -1,12 +1,11 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import typing as ta
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            from ... import lang
         
     | 
| 
       4 
     | 
    
         
            -
            from ..elements import  
     | 
| 
      
 4 
     | 
    
         
            +
            from ..elements import CollectedElements
         
     | 
| 
       5 
5 
     | 
    
         
             
            from ..injector import AsyncInjector
         
     | 
| 
       6 
6 
     | 
    
         
             
            from ..inspect import KwargsTarget
         
     | 
| 
       7 
7 
     | 
    
         
             
            from ..keys import Key
         
     | 
| 
       8 
8 
     | 
    
         
             
            from ..sync import Injector
         
     | 
| 
       9 
     | 
    
         
            -
            from .elements import ElementCollection
         
     | 
| 
       10 
9 
     | 
    
         
             
            from .injector import AsyncInjectorImpl
         
     | 
| 
       11 
10 
     | 
    
         | 
| 
       12 
11 
     | 
    
         | 
| 
         @@ -29,10 +28,10 @@ class InjectorImpl(Injector, lang.Final): 
     | 
|
| 
       29 
28 
     | 
    
         
             
                    return lang.sync_await(self._ai.inject(obj))
         
     | 
| 
       30 
29 
     | 
    
         | 
| 
       31 
30 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
            def create_injector( 
     | 
| 
      
 31 
     | 
    
         
            +
            def create_injector(ce: CollectedElements) -> Injector:
         
     | 
| 
       33 
32 
     | 
    
         
             
                si = InjectorImpl()
         
     | 
| 
       34 
33 
     | 
    
         
             
                ai = AsyncInjectorImpl(
         
     | 
| 
       35 
     | 
    
         
            -
                     
     | 
| 
      
 34 
     | 
    
         
            +
                    ce,
         
     | 
| 
       36 
35 
     | 
    
         
             
                    internal_consts={
         
     | 
| 
       37 
36 
     | 
    
         
             
                        Key(Injector): si,
         
     | 
| 
       38 
37 
     | 
    
         
             
                    },
         
     | 
    
        omlish/inject/injector.py
    CHANGED
    
    | 
         @@ -1,9 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import abc
         
     | 
| 
       2 
2 
     | 
    
         
             
            import typing as ta
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
      
 4 
     | 
    
         
            +
            from .. import check
         
     | 
| 
       4 
5 
     | 
    
         
             
            from .. import lang
         
     | 
| 
      
 6 
     | 
    
         
            +
            from .elements import CollectedElements
         
     | 
| 
       5 
7 
     | 
    
         
             
            from .elements import Elemental
         
     | 
| 
       6 
8 
     | 
    
         
             
            from .elements import as_elements
         
     | 
| 
      
 9 
     | 
    
         
            +
            from .elements import collect_elements
         
     | 
| 
       7 
10 
     | 
    
         
             
            from .inspect import KwargsTarget
         
     | 
| 
       8 
11 
     | 
    
         
             
            from .keys import Key
         
     | 
| 
       9 
12 
     | 
    
         | 
| 
         @@ -44,5 +47,31 @@ class AsyncInjector(lang.Abstract): 
     | 
|
| 
       44 
47 
     | 
    
         
             
                    return self.provide(target)
         
     | 
| 
       45 
48 
     | 
    
         | 
| 
       46 
49 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
            ##
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            @ta.final
         
     | 
| 
      
 54 
     | 
    
         
            +
            class _InjectorCreator(ta.Generic[T]):
         
     | 
| 
      
 55 
     | 
    
         
            +
                def __init__(self, fac: ta.Callable[[CollectedElements], T]) -> None:
         
     | 
| 
      
 56 
     | 
    
         
            +
                    self._fac = fac
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                @ta.overload
         
     | 
| 
      
 59 
     | 
    
         
            +
                def __call__(self, es: CollectedElements, /) -> T: ...
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                @ta.overload
         
     | 
| 
      
 62 
     | 
    
         
            +
                def __call__(self, *es: Elemental) -> T: ...
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def __call__(self, arg0, *argv):
         
     | 
| 
      
 65 
     | 
    
         
            +
                    ce: CollectedElements
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if isinstance(arg0, CollectedElements):
         
     | 
| 
      
 67 
     | 
    
         
            +
                        check.arg(not argv)
         
     | 
| 
      
 68 
     | 
    
         
            +
                        ce = arg0
         
     | 
| 
      
 69 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 70 
     | 
    
         
            +
                        ce = collect_elements(as_elements(arg0, *argv))
         
     | 
| 
      
 71 
     | 
    
         
            +
                    return self._fac(ce)
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            ##
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            create_async_injector = _InjectorCreator[ta.Awaitable[AsyncInjector]](lambda ce: _injector.create_async_injector(ce))
         
     | 
    
        omlish/inject/maysync.py
    CHANGED
    
    | 
         @@ -1,8 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import typing as ta
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            from .. import lang
         
     | 
| 
       4 
     | 
    
         
            -
            from . 
     | 
| 
       5 
     | 
    
         
            -
            from .elements import as_elements
         
     | 
| 
      
 4 
     | 
    
         
            +
            from .injector import _InjectorCreator
         
     | 
| 
       6 
5 
     | 
    
         
             
            from .sync import Injector
         
     | 
| 
       7 
6 
     | 
    
         | 
| 
       8 
7 
     | 
    
         | 
| 
         @@ -25,5 +24,4 @@ class MaysyncInjector(Injector, lang.Abstract): 
     | 
|
| 
       25 
24 
     | 
    
         
             
            ##
         
     | 
| 
       26 
25 
     | 
    
         | 
| 
       27 
26 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                return _maysync.create_maysync_injector(as_elements(*args))
         
     | 
| 
      
 27 
     | 
    
         
            +
            create_maysync_injector = _InjectorCreator[MaysyncInjector](lambda ce: _maysync.create_maysync_injector(ce))
         
     | 
    
        omlish/inject/sync.py
    CHANGED
    
    | 
         @@ -2,8 +2,7 @@ import abc 
     | 
|
| 
       2 
2 
     | 
    
         
             
            import typing as ta
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            from .. import lang
         
     | 
| 
       5 
     | 
    
         
            -
            from . 
     | 
| 
       6 
     | 
    
         
            -
            from .elements import as_elements
         
     | 
| 
      
 5 
     | 
    
         
            +
            from .injector import _InjectorCreator
         
     | 
| 
       7 
6 
     | 
    
         
             
            from .inspect import KwargsTarget
         
     | 
| 
       8 
7 
     | 
    
         
             
            from .keys import Key
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
         @@ -44,5 +43,7 @@ class Injector(lang.Abstract): 
     | 
|
| 
       44 
43 
     | 
    
         
             
                    return self.provide(target)
         
     | 
| 
       45 
44 
     | 
    
         | 
| 
       46 
45 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
            ##
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            create_injector = _InjectorCreator[Injector](lambda ce: _sync.create_injector(ce))
         
     | 
    
        omlish/lang/imports/proxy.py
    CHANGED
    
    | 
         @@ -342,6 +342,8 @@ def proxy_import( 
     | 
|
| 
       342 
342 
     | 
    
         
             
                    spec: str,
         
     | 
| 
       343 
343 
     | 
    
         
             
                    package: str | None = None,
         
     | 
| 
       344 
344 
     | 
    
         
             
                    extras: ta.Iterable[str] | None = None,
         
     | 
| 
      
 345 
     | 
    
         
            +
                    *,
         
     | 
| 
      
 346 
     | 
    
         
            +
                    no_cache: bool = False,
         
     | 
| 
       345 
347 
     | 
    
         
             
            ) -> types.ModuleType:
         
     | 
| 
       346 
348 
     | 
    
         
             
                """'Legacy' proxy import mechanism."""
         
     | 
| 
       347 
349 
     | 
    
         | 
| 
         @@ -352,12 +354,19 @@ def proxy_import( 
     | 
|
| 
       352 
354 
     | 
    
         | 
| 
       353 
355 
     | 
    
         
             
                def __getattr__(att):  # noqa
         
     | 
| 
       354 
356 
     | 
    
         
             
                    nonlocal omod
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
       355 
358 
     | 
    
         
             
                    if omod is None:
         
     | 
| 
       356 
359 
     | 
    
         
             
                        omod = importlib.import_module(spec, package=package)
         
     | 
| 
       357 
360 
     | 
    
         
             
                        if extras:
         
     | 
| 
       358 
361 
     | 
    
         
             
                            for x in extras:
         
     | 
| 
       359 
362 
     | 
    
         
             
                                importlib.import_module(f'{spec}.{x}', package=package)
         
     | 
| 
       360 
     | 
    
         
            -
             
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
                    v = getattr(omod, att)
         
     | 
| 
      
 365 
     | 
    
         
            +
             
     | 
| 
      
 366 
     | 
    
         
            +
                    if not no_cache:
         
     | 
| 
      
 367 
     | 
    
         
            +
                        setattr(lmod, att, v)
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
      
 369 
     | 
    
         
            +
                    return v
         
     | 
| 
       361 
370 
     | 
    
         | 
| 
       362 
371 
     | 
    
         
             
                lmod = types.ModuleType(spec)
         
     | 
| 
       363 
372 
     | 
    
         
             
                lmod.__getattr__ = __getattr__  # type: ignore[method-assign]
         
     |