Skip to content

Commit

Permalink
fixes #215
Browse files Browse the repository at this point in the history
  • Loading branch information
jph00 committed Nov 17, 2020
1 parent 0ff4a33 commit cb20f6e
Show file tree
Hide file tree
Showing 7 changed files with 383 additions and 369 deletions.
8 changes: 4 additions & 4 deletions fastcore/_nbdev.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,17 @@
"instantiate": "01_basics.ipynb",
"using_attr": "01_basics.ipynb",
"Self": "01_basics.ipynb",
"copy_func": "01_basics.ipynb",
"patch_to": "01_basics.ipynb",
"patch": "01_basics.ipynb",
"patch_property": "01_basics.ipynb",
"Stateful": "01_basics.ipynb",
"PrettyString": "01_basics.ipynb",
"even_mults": "01_basics.ipynb",
"num_cpus": "01_basics.ipynb",
"defaults.cpus": "01_basics.ipynb",
"add_props": "01_basics.ipynb",
"typed": "01_basics.ipynb",
"copy_func": "02_foundation.ipynb",
"patch_to": "02_foundation.ipynb",
"patch": "02_foundation.ipynb",
"patch_property": "02_foundation.ipynb",
"working_directory": "02_foundation.ipynb",
"add_docs": "02_foundation.ipynb",
"docs": "02_foundation.ipynb",
Expand Down
47 changes: 45 additions & 2 deletions fastcore/basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
'filter_keys', 'filter_values', 'cycle', 'zip_cycle', 'sorted_ex', 'negate_func', 'argwhere', 'filter_ex',
'range_of', 'renumerate', 'first', 'nested_attr', 'nested_idx', 'val2idx', 'uniqueify', 'num_methods',
'rnum_methods', 'inum_methods', 'fastuple', 'arg0', 'arg1', 'arg2', 'arg3', 'arg4', 'bind', 'map_ex',
'compose', 'maps', 'partialler', 'instantiate', 'using_attr', 'Self', 'Self', 'Stateful', 'PrettyString',
'even_mults', 'num_cpus', 'add_props', 'typed']
'compose', 'maps', 'partialler', 'instantiate', 'using_attr', 'Self', 'Self', 'copy_func', 'patch_to',
'patch', 'patch_property', 'Stateful', 'PrettyString', 'even_mults', 'num_cpus', 'add_props', 'typed']

# Cell
from .imports import *
import builtins

# Cell
defaults = SimpleNamespace()
Expand Down Expand Up @@ -688,6 +689,48 @@ def __call__(self,*args,**kwargs): return self.__getattr__('_call')(*args,**kwar
# Cell
#nbdev_comment _all_ = ['Self']

# Cell
def copy_func(f):
"Copy a non-builtin function (NB `copy.copy` does not work for this)"
if not isinstance(f,FunctionType): return copy(f)
fn = FunctionType(f.__code__, f.__globals__, f.__name__, f.__defaults__, f.__closure__)
fn.__kwdefaults__ = f.__kwdefaults__
fn.__dict__.update(f.__dict__)
return fn

# Cell
def patch_to(cls, as_prop=False, cls_method=False):
"Decorator: add `f` to `cls`"
if not isinstance(cls, (tuple,list)): cls=(cls,)
def _inner(f):
for c_ in cls:
nf = copy_func(f)
nm = f.__name__
# `functools.update_wrapper` when passing patched function to `Pipeline`, so we do it manually
for o in functools.WRAPPER_ASSIGNMENTS: setattr(nf, o, getattr(f,o))
nf.__qualname__ = f"{c_.__name__}.{nm}"
if cls_method:
setattr(c_, nm, MethodType(nf, c_))
else:
setattr(c_, nm, property(nf) if as_prop else nf)
# Avoid clobbering existing functions
return globals().get(nm, builtins.__dict__.get(nm, None))
return _inner

# Cell
def patch(f=None, *, as_prop=False, cls_method=False):
"Decorator: add `f` to the first parameter's class (based on f's type annotations)"
if f is None: return partial(patch, as_prop=as_prop, cls_method=cls_method)
cls = next(iter(f.__annotations__.values()))
return patch_to(cls, as_prop=as_prop, cls_method=cls_method)(f)

# Cell
def patch_property(f):
"Deprecated; use `patch(as_prop=True)` instead"
warnings.warn("`patch_property` is deprecated and will be removed; use `patch(as_prop=True)` instead")
cls = next(iter(f.__annotations__.values()))
return patch_to(cls, as_prop=True)(f)

# Cell
class Stateful:
"A base class/mixin for objects that should not serialize all their state"
Expand Down
45 changes: 2 additions & 43 deletions fastcore/foundation.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/02_foundation.ipynb (unless otherwise specified).

__all__ = ['copy_func', 'patch_to', 'patch', 'patch_property', 'working_directory', 'add_docs', 'docs', 'coll_repr',
'is_bool', 'mask2idxs', 'cycle', 'zip_cycle', 'is_indexer', 'GetAttr', 'delegate_attr', 'CollBase', 'L',
'save_config_file', 'read_config_file', 'Config']
__all__ = ['working_directory', 'add_docs', 'docs', 'coll_repr', 'is_bool', 'mask2idxs', 'cycle', 'zip_cycle',
'is_indexer', 'GetAttr', 'delegate_attr', 'CollBase', 'L', 'save_config_file', 'read_config_file', 'Config']

# Cell
from .imports import *
Expand All @@ -13,46 +12,6 @@
from configparser import ConfigParser
import random,pickle

# Cell
def copy_func(f):
"Copy a non-builtin function (NB `copy.copy` does not work for this)"
if not isinstance(f,FunctionType): return copy(f)
fn = FunctionType(f.__code__, f.__globals__, f.__name__, f.__defaults__, f.__closure__)
fn.__kwdefaults__ = f.__kwdefaults__
fn.__dict__.update(f.__dict__)
return fn

# Cell
def patch_to(cls, as_prop=False, cls_method=False):
"Decorator: add `f` to `cls`"
if not isinstance(cls, (tuple,list)): cls=(cls,)
def _inner(f):
for c_ in cls:
nf = copy_func(f)
# `functools.update_wrapper` when passing patched function to `Pipeline`, so we do it manually
for o in functools.WRAPPER_ASSIGNMENTS: setattr(nf, o, getattr(f,o))
nf.__qualname__ = f"{c_.__name__}.{f.__name__}"
if cls_method:
setattr(c_, f.__name__, MethodType(nf, c_))
else:
setattr(c_, f.__name__, property(nf) if as_prop else nf)
return f
return _inner

# Cell
def patch(f=None, *, as_prop=False, cls_method=False):
"Decorator: add `f` to the first parameter's class (based on f's type annotations)"
if f is None: return partial(patch, as_prop=as_prop, cls_method=cls_method)
cls = next(iter(f.__annotations__.values()))
return patch_to(cls, as_prop=as_prop, cls_method=cls_method)(f)

# Cell
def patch_property(f):
"Deprecated; use `patch(as_prop=True)` instead"
warnings.warn("`patch_property` is deprecated and will be removed; use `patch(as_prop=True)` instead")
cls = next(iter(f.__annotations__.values()))
return patch_to(cls, as_prop=True)(f)

# Cell
@contextmanager
def working_directory(path):
Expand Down
3 changes: 2 additions & 1 deletion fastcore/xtras.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,15 @@ def _socket_det(port,host,dgram):
return family,addr,(socket.SOCK_STREAM,socket.SOCK_DGRAM)[dgram]

# Cell
def start_server(port, host=None, dgram=False, n_queue=None):
def start_server(port, host=None, dgram=False, reuse_addr=True, n_queue=None):
"Create a `socket` server on `port`, with optional `host`, of type `dgram`"
listen_args = [n_queue] if n_queue else []
family,addr,typ = _socket_det(port,host,dgram)
if family==socket.AF_UNIX:
if os.path.exists(addr): os.unlink(addr)
assert not os.path.exists(addr), f"{addr} in use"
s = socket.socket(family, typ)
if reuse_addr and family==socket.AF_INET: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(*listen_args)
return s
Expand Down
Loading

0 comments on commit cb20f6e

Please # to comment.