PEP 508 – Python 软件包的依赖性规范- 中文

这篇博客详细介绍了Python第三方库(PyPI)的命名规范,包括名称必须匹配的正则表达式。此外,文章还讨论了额外依赖(Extras),它们允许发行版根据需要指定附加依赖项。 Extras的使用方式和依赖关系的合并规则也进行了阐述。同时,文中给出了版本约束和环境标记(marker)的完整语法规则,用于描述依赖关系的条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(纯为了自己学习记录,大家若有更好的指南请告诉我,最近对第三方库有关内容进行分析,属于一知半解的状态~~~感谢相遇)
原文链接 https://peps.python.org/pep-0508/

第三方库名称

PyPI 对名称设置了严格的限制 - 它们必须与不区分大小写的正则表达式匹配,否则将不被接受。因此,在此 PEP 中,我们将标识符的可接受值限制为该正则表达式。名称的完整重新定义可能会在将来的元数据 PEP 中进行。正则表达式(使用 re.IGNORECASE) 是:

^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$

Extras

发行版可以根据需要指定任意数量的附加项,并且当在依赖关系规范中使用附加项时,每个额外项都会导致分发版的附加依赖项的声明。例如:
requests[security]
Extras 在它们定义的依赖关系中与它们所附加到的发行版的依赖项联合。上面的示例将导致安装请求,并且请求具有自己的依赖项,以及请求的“安全性”中列出的任何依赖项。

如果列出了多个附加项,则所有依赖项将合并在一起。

Complete Grammar

wsp = ’ ’ | ‘\t’
version_cmp = wsp* <‘<=’ | ‘<’ | ‘!=’ | ‘’ | ‘>=’ | ‘>’ | ‘~=’ | '=’>
version = wsp* <( letterOrDigit | ‘-’ | ‘’ | ‘.’ | '’ | ‘+’ | ‘!’ )+>
version_one = version_cmp:op version:v wsp
-> (op, v)
version_many = version_one:v1 (wsp* ‘,’ version_one):v2 -> [v1] + v2
versionspec = (‘(’ version_many:v ‘)’ ->v) | version_many
urlspec = ‘@’ wsp
<URI_reference>
marker_op = version_cmp | (wsp* ‘in’) | (wsp* ‘not’ wsp+ ‘in’)
python_str_c = (wsp | letter | digit | ‘(’ | ‘)’ | ‘.’ | ‘{’ | ‘}’ |
‘-’ | '
’ | ‘’ | ‘#’ | ‘:’ | ‘;’ | ‘,’ | ‘/’ | ‘?’ |
‘[’ | ‘]’ | ‘!’ | ‘~’ | ‘`’ | ‘@’ | ‘$’ | ‘%’ | ‘^’ |
‘&’ | ‘=’ | ‘+’ | ‘|’ | ‘<’ | ‘>’ )
dquote = ‘"’
squote = ‘\’’
python_str = (squote <(python_str_c | dquote)
>:s squote |
dquote <(python_str_c | squote)>:s dquote) -> s
env_var = (‘python_version’ | ‘python_full_version’ |
‘os_name’ | ‘sys_platform’ | ‘platform_release’ |
‘platform_system’ | ‘platform_version’ |
‘platform_machine’ | ‘platform_python_implementation’ |
‘implementation_name’ | ‘implementation_version’ |
‘extra’ # ONLY when defined by a containing layer
):varname -> lookup(varname)
marker_var = wsp
(env_var | python_str)
marker_expr = marker_var:l marker_op:o marker_var:r -> (o, l, r)
| wsp* ‘(’ marker:m wsp* ‘)’ -> m
marker_and = marker_expr:l wsp* ‘and’ marker_expr:r -> (‘and’, l, r)
| marker_expr:m -> m
marker_or = marker_and:l wsp* ‘or’ marker_and:r -> (‘or’, l, r)
| marker_and:m -> m
marker = marker_or
quoted_marker = ‘;’ wsp* marker
identifier_end = letterOrDigit | ((’-’ | ‘_’ | ‘.’ )* letterOrDigit)
identifier = < letterOrDigit identifier_end* >
name = identifier
extras_list = identifier:i (wsp* ‘,’ wsp* identifier):ids -> [i] + ids
extras = ‘[’ wsp
extras_list?:e wsp* ‘]’ -> e
name_req = (name:n wsp* extras?:e wsp* versionspec?:v wsp* quoted_marker?:m
-> (n, e or [], v or [], m))
url_req = (name:n wsp* extras?:e wsp* urlspec:v (wsp+ | end) quoted_marker?:m
-> (n, e or [], v, m))
specification = wsp* ( url_req | name_req )😒 wsp* -> s

The result is a tuple - name, list-of-extras,

list-of-version-constraints-or-a-url, marker-ast or None

URI_reference = <URI | relative_ref>
URI = scheme ‘:’ hier_part (‘?’ query )? ( ‘#’ fragment)?
hier_part = (‘//’ authority path_abempty) | path_absolute | path_rootless | path_empty
absolute_URI = scheme ‘:’ hier_part ( ‘?’ query )?
relative_ref = relative_part ( ‘?’ query )? ( ‘#’ fragment )?
relative_part = ‘//’ authority path_abempty | path_absolute | path_noscheme | path_empty
scheme = letter ( letter | digit | ‘+’ | ‘-’ | ‘.’)*
authority = ( userinfo ‘@’ )? host ( ‘:’ port )?
userinfo = ( unreserved | pct_encoded | sub_delims | ‘:’)*
host = IP_literal | IPv4address | reg_name
port = digit*
IP_literal = ‘[’ ( IPv6address | IPvFuture) ‘]’
IPvFuture = ‘v’ hexdig+ ‘.’ ( unreserved | sub_delims | ‘:’)+
IPv6address = (
( h16 ‘:’){6} ls32
| ‘::’ ( h16 ‘:’){5} ls32
| ( h16 )? ‘::’ ( h16 ‘:’){4} ls32
| ( ( h16 ‘:’)? h16 )? ‘::’ ( h16 ‘:’){3} ls32
| ( ( h16 ‘:’){0,2} h16 )? ‘::’ ( h16 ‘:’){2} ls32
| ( ( h16 ‘:’){0,3} h16 )? ‘::’ h16 ‘:’ ls32
| ( ( h16 ‘:’){0,4} h16 )? ‘::’ ls32
| ( ( h16 ‘:’){0,5} h16 )? ‘::’ h16
| ( ( h16 ‘:’){0,6} h16 )? ‘::’ )
h16 = hexdig{1,4}
ls32 = ( h16 ‘:’ h16) | IPv4address
IPv4address = dec_octet ‘.’ dec_octet ‘.’ dec_octet ‘.’ dec_octet
nz = ~‘0’ digit
dec_octet = (
digit # 0-9
| nz digit # 10-99
| ‘1’ digit{2} # 100-199
| ‘2’ (‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’) digit # 200-249
| ‘25’ (‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’) )# %250-255
reg_name = ( unreserved | pct_encoded | sub_delims)*
path = (
path_abempty # begins with ‘/’ or is empty
| path_absolute # begins with ‘/’ but not ‘//’
| path_noscheme # begins with a non-colon segment
| path_rootless # begins with a segment
| path_empty ) # zero characters
path_abempty = ( ‘/’ segment)*
path_absolute = ‘/’ ( segment_nz ( ‘/’ segment)* )?
path_noscheme = segment_nz_nc ( ‘/’ segment)*
path_rootless = segment_nz ( ‘/’ segment)*
path_empty = pchar{0}
segment = pchar*
segment_nz = pchar+
segment_nz_nc = ( unreserved | pct_encoded | sub_delims | ‘@’)+
# non-zero-length segment without any colon ‘:’
pchar = unreserved | pct_encoded | sub_delims | ‘:’ | ‘@’
query = ( pchar | ‘/’ | ‘?’)*
fragment = ( pchar | ‘/’ | ‘?’)*
pct_encoded = ‘%’ hexdig
unreserved = letter | digit | ‘-’ | ‘.’ | ‘_’ | ‘~’
reserved = gen_delims | sub_delims
gen_delims = ‘:’ | ‘/’ | ‘?’ | ‘#’ | ‘(’ | ‘)?’ | ‘@’
sub_delims = ‘!’ | ‘$’ | ‘&’ | ‘\’’ | ‘(’ | ‘)’ | ‘*’ | ‘+’ | ‘,’ | ‘;’ | ‘=’
hexdig = digit | ‘a’ | ‘A’ | ‘b’ | ‘B’ | ‘c’ | ‘C’ | ‘d’ | ‘D’ | ‘e’ | ‘E’ | ‘f’ | ‘F’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值