Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
01c11bb
Added engine_import implementation.
jordanbriere May 31, 2019
3096e59
Added "ENGINE_IMPORT_SKIPPABLES" containing names to always skip when…
jordanbriere Jun 1, 2019
739870a
Added an example for engine_import.
jordanbriere Jun 12, 2019
ac114bc
NoWeaponManager will now raise a NotImplementedError into __getattr__…
jordanbriere Jun 12, 2019
df646bd
Merge branch 'master' into engine_import
jordanbriere Jun 12, 2019
28ae74d
Added missing declaration for the _weapons module.
jordanbriere Jun 12, 2019
21d09ac
<tab> → <4 spaces>.
jordanbriere Jun 12, 2019
b5d3566
The imported files are inheriting the caller's scope so importing the…
jordanbriere Jun 12, 2019
e95924e
Improved documentation of engine_import by adding information about g…
jordanbriere Jun 12, 2019
d311073
Fixed wrappers for method descriptors.
jordanbriere Jun 12, 2019
c3e92d4
Added an optional self parameter to get_wrapped in order to properly …
jordanbriere Jun 12, 2019
985109d
Fixed a TypeError when the __all__ attribute is not a tuple and made …
jordanbriere Jun 13, 2019
f6cc81f
Removed the players._language module.
jordanbriere Jun 13, 2019
d8ff646
Removed a redundant import.
jordanbriere Jun 13, 2019
9be41d6
Added default fallback for Player.give_named_item and Player.has_c4.
jordanbriere Jun 13, 2019
be58c5b
Added missing documentation for PlayerMixin.
jordanbriere Jun 14, 2019
179f62b
Fixed a TypeError when skippables is not a tuple.
jordanbriere Jun 14, 2019
74765ad
Fixed private class members not being skipped when skip_privates is e…
jordanbriere Jun 14, 2019
d231c8a
Never skip Python's magic methods/members.
jordanbriere Jun 14, 2019
1fdca4f
Reverted 74765ad and d231c8a because if private class members are ski…
jordanbriere Jun 14, 2019
fdc2ab8
Fixed wrap_entity_mem_func decorated methods from being documented as…
jordanbriere Jun 14, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Added engine_import implementation.
  • Loading branch information
jordanbriere committed May 31, 2019
commit 01c11bbbb585beaebb0391e44e181439aa73ce4f

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

70 changes: 68 additions & 2 deletions addons/source-python/packages/source-python/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,23 @@
from collections import defaultdict
# Contextlib
from contextlib import contextmanager
# Functools
from functools import update_wrapper
# Hashlib
import hashlib
# Inspect
from inspect import getmodule
from inspect import currentframe
from inspect import getmodule
from inspect import isclass
from inspect import isfunction
# OS
from os import sep
# Path
from path import Path
# Platform
from platform import system
# Runpy
from runpy import run_path
# Sys
import sys
# Urllib
Expand Down Expand Up @@ -70,9 +76,11 @@
'console_message',
'create_checksum',
'echo_console',
'engine_import',
'get_core_modules',
'get_interface',
'get_public_ip',
'get_wrapped',
'ignore_unicode_errors',
'server_output',
)
Expand Down Expand Up @@ -330,4 +338,62 @@ def check_info_output(output):
if lines[-1].startswith('-'):
lines.pop()

return create_checksum(''.join(lines)) != checksum
return create_checksum(''.join(lines)) != checksum


def engine_import():
"""Import engine/game specific objects.

:raise ImportError:
If it was not called from global scope.
"""
f = currentframe().f_back
if f.f_locals is not f.f_globals:
raise ImportError(
'"engine_import" must only be called from global scopes.')
caller = getmodule(f)
directory, name = Path(caller.__file__).splitpath()
for subfolder in (SOURCE_ENGINE, GAME_NAME):
directory /= subfolder
if not directory.isdir():
break
path = directory / name
if not path.isfile():
continue
for attr, obj in run_path(path, f.f_globals, caller.__name__).items():
if isclass(obj):
base = obj.__base__
if (obj.__name__ == base.__name__ and
base.__module__ == caller.__name__):
for k, v in obj.__dict__.items():
if (k == '__doc__' and
getattr(base, '__doc__', None) is not None):
continue
if isfunction(v) and hasattr(base, k):
func = getattr(base, k)
if isfunction(func):
update_wrapper(v, func)
setattr(base, k, v)
continue
if hasattr(caller, attr):
o = getattr(caller, attr)
if o is obj:
continue
elif isfunction(o):
update_wrapper(obj, o)
setattr(caller, attr, obj)

def get_wrapped(func):
"""Returns the wrapped function of a wrapper function.

:param function func:
The wrapper function to get the wrapped function from.
:raise TypeError:
If the given wrapper is not a function.
:return:
The wrapped function or ``None`` if the given wrapper is not wrapping
any function.
"""
if not isfunction(func):
raise TypeError(f'"{func}" is not a function.')
return getattr(func, '__wrapped__', None)
Loading