Skip to content

Commit 2cd8445

Browse files
committed
rename _providers to _handlers, rename .provider to .binprovider, fix forced cast to superclass BinProvider because of missing InstanceOf type
1 parent 43049da commit 2cd8445

File tree

5 files changed

+219
-199
lines changed

5 files changed

+219
-199
lines changed

README.md

+25-23
Original file line numberDiff line numberDiff line change
@@ -44,33 +44,34 @@ from pydantic_pkgr import *
4444
apt, brew, pip, npm, env = AptProvider(), BrewProvider(), PipProvider(), NpmProvider(), EnvProvider()
4545

4646
dependencies = [
47-
Binary(name='curl', providers=[env, apt, brew]),
48-
Binary(name='wget', providers=[env, apt, brew]),
49-
Binary(name='yt-dlp', providers=[env, pip, apt, brew]),
50-
Binary(name='playwright', providers=[env, pip, npm]),
51-
Binary(name='puppeteer', providers=[env, npm]),
47+
Binary(name='curl', binproviders=[env, apt, brew]),
48+
Binary(name='wget', binproviders=[env, apt, brew]),
49+
Binary(name='yt-dlp', binproviders=[env, pip, apt, brew]),
50+
Binary(name='playwright', binproviders=[env, pip, npm]),
51+
Binary(name='puppeteer', binproviders=[env, npm]),
5252
]
5353
for binary in dependencies:
5454
binary = binary.load_or_install()
5555

56-
print(binary.abspath, binary.version, binary.provider, binary.is_valid)
57-
# Path('/usr/bin/curl') SemVer('7.81.0') 'apt' True
56+
print(binary.abspath, binary.version, binary.binprovider, binary.is_valid)
57+
# Path('/usr/bin/curl') SemVer('7.81.0') AptProvider() True
5858

5959
binary.exec(cmd=['--version']) # curl 7.81.0 (x86_64-apple-darwin23.0) libcurl/7.81.0 ...
6060
```
6161

6262
```python
63+
from pydantic import InstanceOf
6364
from pydantic_pkgr import Binary, BinProvider, BrewProvider, EnvProvider
6465

6566
# you can also define binaries as classes, making them usable for type checking
6667
class CurlBinary(Binary):
6768
name: str = 'curl'
68-
providers: list[BinProvider] = [BrewProvider(), EnvProvider()]
69+
binproviders: List[InstanceOf[BinProvider]] = [BrewProvider(), EnvProvider()]
6970

7071
curl = CurlBinary().install()
71-
assert isinstance(curl, CurlBinary) # CurlBinary is a unique type you can use in annotations now
72-
print(curl.abspath, curl.version, curl.provider, curl.is_valid) # Path('/opt/homebrew/bin/curl') SemVer('8.4.0') 'brew' True
73-
curl.exec(cmd=['--version']) # curl 8.4.0 (x86_64-apple-darwin23.0) libcurl/8.4.0 ...
72+
assert isinstance(curl, CurlBinary) # CurlBinary is a unique type you can use in annotations now
73+
print(curl.abspath, curl.version, curl.binprovider, curl.is_valid) # Path('/opt/homebrew/bin/curl') SemVer('8.4.0') BrewProvider() True
74+
curl.exec(cmd=['--version']) # curl 8.4.0 (x86_64-apple-darwin23.0) libcurl/8.4.0 ...
7475
```
7576

7677
```python
@@ -150,7 +151,7 @@ curl.exec(['--version']) # curl 7.81.0 (x86_64-pc-linux-gnu) libcur
150151

151152
### Example: Finding/Installing django with pip (w/ customized binpath resolution behavior)
152153
pip = PipProvider(
153-
abspath_provider={'*': lambda bin_name, **context: inspect.getfile(bin_name)}, # use python inspect to get path instead of os.which
154+
abspath_handler={'*': lambda bin_name, **context: inspect.getfile(bin_name)}, # use python inspect to get path instead of os.which
154155
)
155156
django_bin = pip.load_or_install(bin_name='django')
156157
print(django_bin.abspath) # Path('/usr/lib/python3.10/site-packages/django/__init__.py')
@@ -164,7 +165,7 @@ It can define one or more `BinProvider`s that it supports, along with overrides
164165

165166
`Binary`s implement the following interface:
166167
- `load()`, `install()`, `load_or_install()` `->` `Binary`
167-
- `provider: BinProviderName` (`BinProviderName == str`)
168+
- `binprovider: InstanceOf[BinProvider]`
168169
- `abspath: Path`
169170
- `abspaths: List[Path]`
170171
- `version: SemVer`
@@ -177,7 +178,7 @@ class YtdlpBinary(Binary):
177178
name: BinName = 'ytdlp'
178179
description: str = 'YT-DLP (Replacement for YouTube-DL) Media Downloader'
179180

180-
providers_supported: List[BinProvider] = [EnvProvider(), PipProvider(), AptProvider(), BrewProvider()]
181+
binproviders_supported: List[BinProvider] = [EnvProvider(), PipProvider(), AptProvider(), BrewProvider()]
181182

182183
# customize installed package names for specific package managers
183184
provider_overrides: Dict[BinProviderName, ProviderLookupDict] = {
@@ -187,7 +188,7 @@ class YtdlpBinary(Binary):
187188
}
188189

189190
ytdlp = YtdlpBinary().load_or_install()
190-
print(ytdlp.provider) # 'brew'
191+
print(ytdlp.binprovider) # BrewProvider(...)
191192
print(ytdlp.abspath) # Path('/opt/homebrew/bin/yt-dlp')
192193
print(ytdlp.abspaths) # [Path('/opt/homebrew/bin/yt-dlp'), Path('/usr/local/bin/yt-dlp')]
193194
print(ytdlp.version) # SemVer('2024.4.9')
@@ -201,7 +202,7 @@ from pydantic_pkgr import BinProvider, Binary, BinProviderName, BinName, Provide
201202
class DockerBinary(Binary):
202203
name: BinName = 'docker'
203204

204-
providers_supported: List[BinProvider] = [EnvProvider(), AptProvider()]
205+
binproviders_supported: List[BinProvider] = [EnvProvider(), AptProvider()]
205206

206207
provider_overrides: Dict[BinProviderName, ProviderLookupDict] = {
207208
'env': {
@@ -219,7 +220,7 @@ class DockerBinary(Binary):
219220
}
220221

221222
docker = DockerBinary().load_or_install()
222-
print(docker.provider) # 'env'
223+
print(docker.binprovider) # EnvProvider()
223224
print(docker.abspath) # Path('/usr/local/bin/podman')
224225
print(docker.abspaths) # [Path('/usr/local/bin/podman'), Path('/opt/homebrew/bin/podman')]
225226
print(docker.version) # SemVer('6.0.2')
@@ -229,7 +230,7 @@ print(docker.is_valid) # True
229230
# e.g. if you want to force the abspath to be at a specific path:
230231
custom_docker = DockerBinary(abspath='~/custom/bin/podman').load()
231232
print(custom_docker.name) # 'docker'
232-
print(custom_docker.provider) # 'env'
233+
print(custom_docker.binprovider) # EnvProvider()
233234
print(custom_docker.abspath) # Path('/Users/example/custom/bin/podman')
234235
print(custom_docker.version) # SemVer('5.0.2')
235236
print(custom_docker.is_valid) # True
@@ -282,15 +283,16 @@ pip install django-pydantic-field
282283

283284
Example Django `models.py` showing how to store `Binary` and `BinProvider` instances in DB fields:
284285
```python
286+
from typing import List
285287
from django.db import models
286-
from django_pydantic_field import SchemaField
287-
288+
from pydantic import InstanceOf
288289
from pydantic_pkgr import BinProvider, Binary, SemVer
290+
from django_pydantic_field import SchemaField
289291

290292
class InstalledBinary(models.Model):
291293
name = models.CharField(max_length=63)
292294
binary: Binary = SchemaField()
293-
providers: list[BinProvider] = SchemaField(default=[])
295+
binproviders: List[InstanceOf[BinProvider]] = SchemaField(default=[])
294296
version: SemVer = SchemaField(default=(0,0,1))
295297
```
296298

@@ -303,7 +305,7 @@ curl = Binary(name='curl').load()
303305
obj = InstalledBinary(
304306
name='curl',
305307
binary=curl, # store Binary/BinProvider/SemVer values directly in fields
306-
providers=[env], # no need for manual JSON serialization / schema checking
308+
binproviders=[env], # no need for manual JSON serialization / schema checking
307309
min_version=SemVer('6.5.0'),
308310
)
309311
obj.save()
@@ -454,7 +456,7 @@ class CargoProvider(BinProvider):
454456

455457
cargo = CargoProvider()
456458
rg = cargo.install(bin_name='ripgrep')
457-
print(rg.provider) # 'cargo'
459+
print(rg.binprovider) # CargoProvider()
458460
print(rg.version) # SemVer(14, 1, 0)
459461
```
460462

0 commit comments

Comments
 (0)