# Buggy code
def create(
    click_config,
    # Stake Options
    poa,
    light,
    registry_filepath,
    config_file,
    provider_uri,
    staking_address,
    hw_wallet,
    beneficiary_address,
    allocation_filepath,
    # Other
    force,
    value,
    lock_periods,
):
    """
    Initialize a new stake.
    """

    ### Setup ###
    emitter = _setup_emitter(click_config)

    STAKEHOLDER, blockchain = _create_stakeholder(
        config_file,
        provider_uri,
        poa,
        light,
        registry_filepath,
        staking_address,
        beneficiary_address=beneficiary_address,
        allocation_filepath=allocation_filepath,
    )
    #############

    economics = STAKEHOLDER.economics

    client_account, staking_address = handle_client_account_for_staking(
        emitter=emitter,
        stakeholder=STAKEHOLDER,
        staking_address=staking_address,
        individual_allocation=STAKEHOLDER.individual_allocation,
        force=force,
    )

    # Dynamic click types (Economics)
    min_locked = economics.minimum_allowed_locked
    stake_value_range = click.FloatRange(
        min=NU.from_nunits(min_locked).to_tokens(), clamp=False
    )
    stake_duration_range = click.IntRange(
        min=economics.minimum_locked_periods, clamp=False
    )

    password = None
    if not hw_wallet and not blockchain.client.is_local:
        password = get_client_password(checksum_address=client_account)

    #
    # Stage Stake
    #

    if not value:
        value = click.prompt(
            f"Enter stake value in NU "
            f"({NU.from_nunits(STAKEHOLDER.economics.minimum_allowed_locked)} - "
            f"{NU.from_nunits(STAKEHOLDER.economics.maximum_allowed_locked)})",
            type=stake_value_range,
            default=NU.from_nunits(min_locked).to_tokens(),
        )
    value = NU.from_tokens(value)

    if not lock_periods:
        prompt = f"Enter stake duration ({STAKEHOLDER.economics.minimum_locked_periods} periods minimum)"
        lock_periods = click.prompt(prompt, type=stake_duration_range)

    start_period = STAKEHOLDER.staking_agent.get_current_period() + 1
    unlock_period = start_period + lock_periods

    #
    # Review
    #

    if not force:
        painting.paint_staged_stake(
            emitter=emitter,
            stakeholder=STAKEHOLDER,
            staking_address=staking_address,
            stake_value=value,
            lock_periods=lock_periods,
            start_period=start_period,
            unlock_period=unlock_period,
        )

        confirm_staged_stake(
            staker_address=staking_address, value=value, lock_periods=lock_periods
        )

    # Last chance to bail
    click.confirm("Publish staged stake to the blockchain?", abort=True)

    # Execute
    STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
    new_stake = STAKEHOLDER.initialize_stake(amount=value, lock_periods=lock_periods)

    painting.paint_staking_confirmation(
        emitter=emitter, ursula=STAKEHOLDER, transactions=new_stake.transactions
    )


# Traceback (AttributeError)
____    __            __
/\  _`\ /\ \__        /\ \
\ \,\L\_\ \ ,_\    __ \ \ \/'\      __   _ __
\/_\__ \\ \ \/  /'__`\\ \ , <    /'__`\/\`'__\
/\ \L\ \ \ \_/\ \L\.\\ \ \\`\ /\  __/\ \ \/
\ `\____\ \__\ \__/.\_\ \_\ \_\ \____\\ \_\
\/_____/\/__/\/__/\/_/\/_/\/_/\/____/ \/_/

The Holder of Stakes.

======================================= Active Stakes =========================================

| ~ | Staker | Worker | # | Value    | Duration     | Enactment
|   | ------ | ------ | - | -------- | ------------ | -----------------------------------------
| 0 | 0xFD3D | 0x1368 | 0 | 15000 NU | 45 periods . | Aug 06 21:00:30 PDT - Sep 20 21:00:30 PDT
| 1 | 0xFD3D | 0x1368 | 1 | 100000 NU | 300 periods  | Oct 01 21:00:30 PDT - Jul 27 21:00:30 PDT
| 2 | 0x9CA6 | 0x3d51 | 0 | 175864.607570726413344034 NU | 33 periods . | Aug 25 21:00:30 PDT - Sep 27 21:00:30 PDT
| 3 | 0x9CA6 | 0x3d51 | 1 | 200000 NU | 365 periods  | Oct 01 21:00:30 PDT - Sep 30 21:00:30 PDT
| 4 | 0x26FD | 0x4801 | 0 | 50000 NU | 60 periods . | Sep 01 21:00:30 PDT - Oct 31 21:00:30 PDT

Select Stake: 4
Enter target value (must be less than or equal to 50000 NU): 40000
Enter number of periods to extend: 250
Traceback (most recent call last):
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/bin/nucypher", line 11, in <module>
load_entry_point('nucypher', 'console_scripts', 'nucypher')()
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/decorators.py", line 64, in new_func
return ctx.invoke(f, obj, *args, **kwargs)
File "/home/michwill/.local/share/virtualenvs/nucypher-kms-5SSQ9ZHE/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/config.py", line 217, in wrapper
return func(config, *args, **kwargs)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/characters/stake.py", line 365, in stake
extension=extension)
File "/home/michwill/Projects/nucypher-kms/nucypher/cli/painting.py", line 406, in paint_staged_stake_division
new_end_period = original_stake.end_period + extension
AttributeError: 'Stake' object has no attribute 'end_period'
Sentry is attempting to send 0 pending error messages
Waiting up to 2.0 seconds
Press Ctrl-C to quit

# Fixed code
def create(
    click_config,
    # Stake Options
    poa,
    light,
    registry_filepath,
    config_file,
    provider_uri,
    staking_address,
    hw_wallet,
    beneficiary_address,
    allocation_filepath,
    # Other
    force,
    value,
    lock_periods,
):
    """
    Initialize a new stake.
    """

    ### Setup ###
    emitter = _setup_emitter(click_config)

    STAKEHOLDER, blockchain = _create_stakeholder(
        config_file,
        provider_uri,
        poa,
        light,
        registry_filepath,
        staking_address,
        beneficiary_address=beneficiary_address,
        allocation_filepath=allocation_filepath,
    )
    #############

    economics = STAKEHOLDER.economics

    client_account, staking_address = handle_client_account_for_staking(
        emitter=emitter,
        stakeholder=STAKEHOLDER,
        staking_address=staking_address,
        individual_allocation=STAKEHOLDER.individual_allocation,
        force=force,
    )

    # Dynamic click types (Economics)
    min_locked = economics.minimum_allowed_locked
    stake_value_range = click.FloatRange(
        min=NU.from_nunits(min_locked).to_tokens(), clamp=False
    )
    stake_duration_range = click.IntRange(
        min=economics.minimum_locked_periods, clamp=False
    )

    password = None
    if not hw_wallet and not blockchain.client.is_local:
        password = get_client_password(checksum_address=client_account)

    #
    # Stage Stake
    #

    if not value:
        value = click.prompt(
            f"Enter stake value in NU "
            f"({NU.from_nunits(STAKEHOLDER.economics.minimum_allowed_locked)} - "
            f"{NU.from_nunits(STAKEHOLDER.economics.maximum_allowed_locked)})",
            type=stake_value_range,
            default=NU.from_nunits(min_locked).to_tokens(),
        )
    value = NU.from_tokens(value)

    if not lock_periods:
        prompt = (
            f"Enter stake duration ({STAKEHOLDER.economics.minimum_locked_periods} - "
            f"{STAKEHOLDER.economics.maximum_rewarded_periods})"
        )
        lock_periods = click.prompt(prompt, type=stake_duration_range)

    start_period = STAKEHOLDER.staking_agent.get_current_period() + 1
    unlock_period = start_period + lock_periods

    #
    # ReviewPub
    #

    if not force:
        painting.paint_staged_stake(
            emitter=emitter,
            stakeholder=STAKEHOLDER,
            staking_address=staking_address,
            stake_value=value,
            lock_periods=lock_periods,
            start_period=start_period,
            unlock_period=unlock_period,
        )

        confirm_staged_stake(
            staker_address=staking_address, value=value, lock_periods=lock_periods
        )

    # Last chance to bail
    click.confirm("Publish staged stake to the blockchain?", abort=True)

    # Execute
    STAKEHOLDER.assimilate(checksum_address=client_account, password=password)
    new_stake = STAKEHOLDER.initialize_stake(amount=value, lock_periods=lock_periods)

    painting.paint_staking_confirmation(
        emitter=emitter, ursula=STAKEHOLDER, transactions=new_stake.transactions
    )