Delegator is a simple library that deals with sub processes inspired by both envoy.
What is delegation?
Delegation is an object-oriented process also known as design pattern). It depends upon the dynamic binding because it requires a given method call to invoke different segments of code at runtime. The delegation technique is used throughout macOS along with its predecessor NeXTStep for customizing the behaviour of program components. It allows implementations like making use of a single OS-provided class for the managing of processing windows.
For example, when you click the close box, the window manager may send the delegate a windowShouldClose; call and the delegate can hold up the window closing (if there is unsaved content represented by the window’s data). Let’s say you have a datum x and want to change its behaviour of just one of its procedures.
You can also form a new class in order to provide a new implementation of the procedure you’re interested in altering and delegate all other procedures to the corresponding procedure of x. Delegation processing is slow, specifically when dependent on reflection or metaprogramming articles. But python programmers can implement delegation in a short time and with much ease.
Delegator.py
Different rankings of several classes use a delegator. Delegator.py is program-specific and can override default behaviour when needed. It is a simple library for dealing with subprocesses, bring about by both envoy and pexpect (actually, it depends on it!). It includes two main functions “delegator.run()” and “delegator.chain()”. First, one commands, blocking or non-blocking while the second one runs a chain of commands, separated by the standard unix pipe operator: “|”.
It’s often easy to delegate this method to a composed object or a constant. ‘Def delegator’ helper method helps build delegators easily and Rails’ ActiveSupport facilitates the builtin interface with delegates.
Delegation based on ‘getattr'
and ‘getattribute’
is complex. It also requires a fair knowledge of Python’s low-level details to implement accurately. Its interaction with the descriptor protocol, and introspection icons such as dir()
or help()
, and with other dunder methods like ‘str’
or ‘add’,
you cannot inherently delegate dunder processes, but you need to implement a method that works the delegation.
Read Also: Everything You Need To Know About Databases In Biological Experiments
Delegation Pattern in Python
Delegation patterns in Python frequently use attribute access to apply the delegated service. There may be a need to re-define all the delegator processes. The implementation of the delegator pattern involves the class inheritance that explicitly supports the delegation of service to another object. It also provides an implicit interface to the service within the user-manipulated object
Not only the delegation is unseen to the interface user, but there are several interface systems that are well defined with named arguments, documentation, and default values. You can also use this method with multiple inheritances to build a mixin class for the aggregation of services.
Example #1
Author: pypa File: core.py License: MIT License
def pip_download(package_name):
cache_dir = vistir.compat.Path(PIPENV_CACHE_DIR)
pip_config = {
"PIP_CACHE_DIR": vistir.misc.fs_str(cache_dir.as_posix()),
"PIP_WHEEL_DIR": vistir.misc.fs_str(cache_dir.joinpath("wheels").as_posix()),
"PIP_DESTINATION_DIR": vistir.misc.fs_str(
cache_dir.joinpath("pkgs").as_posix()
),
for source in project.sources:
cmd = '{0} download "{1}" -i {2} -d {3}'.format(
escape_grouped_arguments(which_pip()),
package_name,
source["url"],
project.download_location,
)
c = delegator.run(cmd, env=pip_config)
if c.return_code == 0:
break return
Example #2
Author: pypa File: test_install_uri.py License: MIT License
def test_install_local_vcs_not_in_lockfile(PipenvInstance):
with PipenvInstance(chdir=True) as p:
# six_path = os.path.join(p.path, "six")
six_path = p._pipfile.get_fixture_path("git/six/").as_posix()
c = delegator.run("git clone {0} ./six".format(six_path))
assert c.return_code == 0
c = p.pipenv("install -e ./six".format(six_path))
assert c.return_code == 0
six_key = list(p.pipfile["packages"].keys())[0]
# we don't need the rest of the test anymore, this just works on its own
assert six_key == "six"
Example #3
Author: jazzband-roadies File: views.py License: MIT License
def post(self, name, upload_id):
if not current_app.config["RELEASE_ENABLED"]:
message = "Releasing is currently out of service"
flash(message)
logging.info(message)
if self.upload.released_at:
flash(
f"The upload {self.upload.filename} has already been released "
f"and can't be released again."
)
return self.redirect_to_project()
release_form = ReleaseForm(project_name=self.project.name)
context = {
"release_form": release_form,
"project": self.project,
"upload": self.upload,
}
if release_form.validate_on_submit():
# copy path to new tmp directory
with tempfile.TemporaryDirectory() as tmpdir:
upload_path = os.path.join(tmpdir, self.upload.filename)
shutil.copy(self.upload.full_path, upload_path)
# run twine upload against copied upload file
twine_run = delegator.run(f"twine upload {upload_path}")
if twine_run.return_code == 0:
errors = self.validate_upload()
release_form.add_global_error(*errors)
if not errors:
# create ProjectRelease object with reference to project
self.upload.released_at = datetime.utcnow()
# write to database
self.upload.save()
message = f"You've successfully released {self.upload} to PyPI."
flash(message)
logger.info(message)
return self.redirect_to_project()
else:
error = f"Release of {self.upload} failed."
release_form.add_global_error(error)
logger.error(
error, extra={"data": {"out": twine_run.out, "err": twine_run.err}}
)
context.update({"twine_run": twine_run, "upload": self.upload})
return context
Example #4
Author: niklas-heer File: comparison.py License: MIT License
def run(self):
"""Run a measurement.
Returns:
list -- List of results.
"""
print(f"> {self.name}")
if self.compile_cmd:
cmd_compile = delegator.run(self.compile_cmd)
if self.debug or cmd_compile.return_code is not 0:
logging.info(cmd_compile.out)
print(f"Version: {delegator.run(self.version_cmd).out.splitlines()[0]}")
times = []
count = 0
while count < 10:
count += 1
# Measure execution time
watch = StopWatch()
watch.start()
cmd_run = delegator.run(self.run_cmd)
watch.stop()
# Convert the measurement into milliseconds
times.append(int(watch.elapsed_time * 1000))
print(f"Speed (all): {'ms, '.join(map(str, times))}ms")
print(f"Speed (best): {min(times)}ms")
print(f"Speed (worst): {max(times)}ms")
print(f"Speed (median): {statistics.median(times)}ms")
# Strip output from new line
result = cmd_run.out.strip()
print(f"Result: {result}")
# Calculate accuracy
if not self.debug:
accuracy = self.diff_letters(f"{math.pi:.{len(result)-2}f}", result)
print(f"Accuracy: {accuracy:.2%}")
else:
accuracy = 0.0000
print() # new line
self.results["median"] = statistics.median(times)
self.results["best"] = min(times)
self.results["worst"] = max(times) self.results["accuracy"] = f"{accuracy*100:.4}"
return self.results
Example #5
Author: kennethreitz-archive File: cache.py License: ISC License
def __getitem__(self, k):
key = self._key_for_hashes(k)
cmd = f"git config --local --get {key}"
if self.debug:
click.echo(f" {click.style('$', fg='green')} {cmd}", err=True)
c = delegator.run(cmd)
if c.ok:
return c.out.strip()
else:
return None