]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/setuptools/depends.py
6 from setuptools
.extern
.packaging
import version
8 from ._imp
import find_module
, PY_COMPILED
, PY_FROZEN
, PY_SOURCE
12 __all__
= ['Require', 'find_module', 'get_module_constant', 'extract_constant']
16 """A prerequisite to building or installing a distribution"""
19 self
, name
, requested_version
, module
, homepage
='', attribute
=None, format
=None
21 if format
is None and requested_version
is not None:
22 format
= version
.Version
24 if format
is not None:
25 requested_version
= format(requested_version
)
27 attribute
= '__version__'
29 self
.__dict
__.update(locals())
33 """Return full package/distribution name, w/version"""
34 if self
.requested_version
is not None:
35 return '%s-%s' % (self
.name
, self
.requested_version
)
38 def version_ok(self
, version
):
39 """Is 'version' sufficiently up-to-date?"""
41 self
.attribute
is None
42 or self
.format
is None
43 or str(version
) != "unknown"
44 and self
.format(version
) >= self
.requested_version
47 def get_version(self
, paths
=None, default
="unknown"):
48 """Get version number of installed module, 'None', or 'default'
50 Search 'paths' for module. If not found, return 'None'. If found,
51 return the extracted version attribute, or 'default' if no version
52 attribute was specified, or the value cannot be determined without
53 importing the module. The version is formatted according to the
54 requirement's version format (if any), unless it is 'None' or the
58 if self
.attribute
is None:
60 f
, p
, i
= find_module(self
.module
, paths
)
67 v
= get_module_constant(self
.module
, self
.attribute
, default
, paths
)
69 if v
is not None and v
is not default
and self
.format
is not None:
74 def is_present(self
, paths
=None):
75 """Return true if dependency is present on 'paths'"""
76 return self
.get_version(paths
) is not None
78 def is_current(self
, paths
=None):
79 """Return true if dependency is present and up-to-date on 'paths'"""
80 version
= self
.get_version(paths
)
83 return self
.version_ok(str(version
))
87 @contextlib.contextmanager
95 return contextlib
.closing(f
)
98 def get_module_constant(module
, symbol
, default
=-1, paths
=None):
99 """Find 'module' by searching 'paths', and extract 'symbol'
101 Return 'None' if 'module' does not exist on 'paths', or it does not define
102 'symbol'. If the module defines 'symbol' as a constant, return the
103 constant. Otherwise, return 'default'."""
106 f
, path
, (suffix
, mode
, kind
) = info
= find_module(module
, paths
)
108 # Module doesn't exist
112 if kind
== PY_COMPILED
:
113 f
.read(8) # skip magic & date
114 code
= marshal
.load(f
)
115 elif kind
== PY_FROZEN
:
116 code
= _imp
.get_frozen_object(module
, paths
)
117 elif kind
== PY_SOURCE
:
118 code
= compile(f
.read(), path
, 'exec')
120 # Not something we can parse; we'll have to import it. :(
121 imported
= _imp
.get_module(module
, paths
, info
)
122 return getattr(imported
, symbol
, None)
124 return extract_constant(code
, symbol
, default
)
127 def extract_constant(code
, symbol
, default
=-1):
128 """Extract the constant value of 'symbol' from 'code'
130 If the name 'symbol' is bound to a constant value by the Python code
131 object 'code', return that value. If 'symbol' is bound to an expression,
132 return 'default'. Otherwise, return 'None'.
134 Return value is based on the first assignment to 'symbol'. 'symbol' must
135 be a global, or at least a non-"fast" local in the code block. That is,
136 only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol'
137 must be present in 'code.co_names'.
139 if symbol
not in code
.co_names
:
140 # name's not there, can't possibly be an assignment
143 name_idx
= list(code
.co_names
).index(symbol
)
151 for byte_code
in dis
.Bytecode(code
):
152 op
= byte_code
.opcode
156 const
= code
.co_consts
[arg
]
157 elif arg
== name_idx
and (op
== STORE_NAME
or op
== STORE_GLOBAL
):
163 def _update_globals():
165 Patch the globals to remove the objects not available on some platforms.
167 XXX it'd be better to test assertions about bytecode instead.
170 if not sys
.platform
.startswith('java') and sys
.platform
!= 'cli':
172 incompatible
= 'extract_constant', 'get_module_constant'
173 for name
in incompatible
: