Python Forum
Error: "Can't set attribute"
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Error: "Can't set attribute"
#1
Hello,

I added a setter, but I still get an error. What do I do wrong?
The class is pretty big so I posted just these pieces of code.

@property
    def deadline(self):
        """
        Deadline in milliseconds.
        """
        return self._task_info.deadline
    
    #Added
    @deadline.setter
    def deadline(self, value):
        self._task_info.deadline = value
I want to set the attribute like this:
task.deadline = 22222

And get the error.
Reply
#2
1) The decorator @property must be correctly aligned with the method.
@property
def deadline(self):
2) what error? Shall we pick a random error we can think of?
Reply
#3
I get the error: " Can't set attribute"
Reply
#4
(Jun-24-2019, 03:57 PM)ThomasL Wrote: 1) The decorator @property must be correctly aligned with the method.
@property
def deadline(self):
2) what error? Shall we pick a random error we can think of?

1) Of course.
2) I get the following error: "Can't set attribute"
Reply
#5
When do you get the error?
What do you do?
Show the complete error message.
Reply
#6
(Jun-24-2019, 04:09 PM)ThomasL Wrote: When do you get the error?
What do you do?
Show the complete error message.

I get the error when I try to run the program.
I have another .py file called EDV_VD.py where I wrote " task.deadline=2222 " in the 'init' function and I get this error:

Traceback (most recent call last):
File "script.py", line 53, in <module>
main(sys.argv)
File "script.py", line 47, in main
model.run_model()
File "C:\Users\norica\AppData\Local\Programs\Python\Python37\lib\site-packages\simso\core\Model.py", line 133, in run_model
self.scheduler.init()
File "./..//simso//schedulers\EDF_VD.py", line 57, in init
task.deadline = 2222
AttributeError: can't set attribute
Reply
#7
and task is an instance of that class where the method deadline is defined?

what construct is self._task_info?
why is there a self._task_info dot deadline?
Reply
#8
https://github.com/MaximeCheramy/simso/b...sk.py#L170 Wrote:
    @property
    def deadline(self):
        """
        Deadline in milliseconds.
        """
        return self._task_info.deadline

Are you modifying a library or something? Can you share your whole class, and how you're trying to use it?
Reply
#9
(Jun-24-2019, 04:47 PM)ThomasL Wrote: and task is an instance of that class where the method deadline is defined?

what construct is self._task_info?
why is there a self._task_info dot deadline?

1. Yes.
2 & 3. Here is the file where I tried to add the setter. It's at line 184.

# coding=utf-8

from collections import deque
from SimPy.Simulation import Process, Monitor, hold, passivate
from simso.core.Job import Job
from simso.core.Timer import Timer
from simso.core.CSDP import CSDP

import os
import os.path


class TaskInfo(object):
    """
    TaskInfo is mainly a container class grouping the data that characterize
    a Task. A list of TaskInfo objects are passed to the Model so that
    :class:`Task` instances can be created.
    """

    def __init__(self, name, identifier, task_type, abort_on_miss, period,
                 activation_date, n_instr, mix, stack_file, wcet, acet,
                 et_stddev, deadline, base_cpi, followed_by,
                 list_activation_dates, preemption_cost, data, my_parameter):
        """
        :type name: str
        :type identifier: int
        :type task_type: str
        :type abort_on_miss: bool
        :type period: float
        :type activation_date: float
        :type n_instr: int
        :type mix: float
        :type stack_file: str
        :type wcet: float
        :type acet: float
        :type et_stddev: float
        :type deadline: float
        :type base_cpi: float
        :type followed_by: int
        :type list_activation_dates: list
        :type preemption_cost: int
        :type data: dict
        :type my_parameter: float
        """
        self.name = name
        self.identifier = identifier
        self.task_type = task_type
        self.period = period
        self.activation_date = activation_date
        self.n_instr = n_instr
        self.mix = mix
        self.wcet = wcet
        self.acet = acet
        self.et_stddev = et_stddev
        self.base_cpi = base_cpi
        self._stack = None
        self._csdp = None
        self._stack_file = ''
        self.set_stack_file(*stack_file)
        self.deadline = deadline
        self.followed_by = followed_by
        self.abort_on_miss = abort_on_miss
        self.list_activation_dates = list_activation_dates
        self.data = data
        self.preemption_cost = preemption_cost
        self.my_parameter = my_parameter

    @property
    def csdp(self):
        """
        Accumulated Stack Distance Profile. Used by the cache models instead of
        the Stack Distance Profile for optimization matters.
        """
        return self._csdp

    @property
    def stack_file(self):
        """
        Stack distance profile input file.
        """
        return self._stack_file

    def set_stack_file(self, stack_file, cur_dir):
        """
        Set the stack distance profile.
        """
        if stack_file:
            try:
                self._stack = TaskInfo._parse_stack(stack_file)
                self._csdp = CSDP(self._stack)
                self._stack_file = os.path.relpath(stack_file, cur_dir)
            except Exception as e:
                print("set_stack_file failed:", e)

    @staticmethod
    def _parse_stack(stack_file):
        stack = {}
        if stack_file and os.path.isfile(stack_file):
            for line in open(stack_file):
                dist, value = line.split()
                stack[int(dist)] = float(value)
        else:
            stack = None
        return stack


class GenericTask(Process):
    """
    Abstract class for Tasks. :class:`ATask` and :class:`PTask` inherits from
    this class.

    These classes simulate the behavior of the simulated task. It controls the
    release of the jobs and is able to abort the jobs that exceed their
    deadline.

    The majority of the task_info attributes are available through this class
    too. A set of metrics such as the number of preemptions and migrations are
    available for analysis.
    """
    fields = []

    def __init__(self, sim, task_info):
        """
        Args:

        - `sim`: :class:`Model <simso.core.Model>` instance.
        - `task_info`: A :class:`TaskInfo` representing the Task.

        :type sim: Model
        :type task_info: TaskInfo
        """
        Process.__init__(self, name=task_info.name, sim=sim)
        self.name = task_info.name
        self._task_info = task_info
        self._monitor = Monitor(name="Monitor" + self.name + "_states",
                                sim=sim)
        self._activations_fifo = deque([])
        self._sim = sim
        self.cpu = None
        self._etm = sim.etm
        self._job_count = 0
        self._last_cpu = None
        self._cpi_alone = {}
        self._jobs = []
        self.job = None
        
        

    def __lt__(self, other):
        return self.identifier < other.identifier

    def is_active(self):
        return self.job is not None and self.job.is_active()

    def set_cpi_alone(self, proc, cpi):
        self._cpi_alone[proc] = cpi

    def get_cpi_alone(self, proc=None):
        if proc is None:
            proc = self.cpu
        return self._cpi_alone[proc]

    @property
    def base_cpi(self):
        return self._task_info.base_cpi

    @property
    def data(self):
        """
        Extra data to characterize the task. Only used by the scheduler.
        """
        return self._task_info.data

    @property
    def deadline(self):
        """
        Deadline in milliseconds.
        """
        return self._task_info.deadline
    
    #Added
    @deadline.setter
    def deadline(self, value):
        self._task_info.deadline = value
    

    

    @property
    def n_instr(self):
        return self._task_info.n_instr

    @property
    def mix(self):
        return self._task_info.mix

    @property
    def csdp(self):
        return self._task_info.csdp

    @property
    def preemption_cost(self):
        return self._task_info.preemption_cost

    @property
    def footprint(self):
        return int(self._task_info.n_instr * self._task_info.mix *
                   (1 - self._task_info.csdp.get(-1)))

    @property
    def wcet(self):
        """Worst-Case Execution Time in milliseconds."""
        return self._task_info.wcet
    #Added
    @wcet.setter
    def set_wcet(self, value):
        'setting'
        self._task_info.wcet = value


    @property
    def acet(self):
        return self._task_info.acet
    
    @property
    def my_parameter(self):
        return self._task_info.my_parameter

    @property
    def et_stddev(self):
        return self._task_info.et_stddev

    @property
    def period(self):
        """
        Period of the task.
        """
        return self._task_info.period

    #Added
    @period.setter
    def period(self,value):
        'setting'
        self._task_info.period = value


    @property
    def identifier(self):
        """
        Identifier of the task.
        """
        return self._task_info.identifier

    @property
    def monitor(self):
        """
        The monitor for this Task. Similar to a log mechanism (see Monitor in
        SimPy doc).
        """
        return self._monitor

    @property
    def followed_by(self):
        """
        Task that is activated by the end of a job from this task.
        """
        if self._task_info.followed_by is not None:
            followed = [x for x in self._sim.task_list
                        if (x.identifier == self._task_info.followed_by)]
            if followed:
                return followed[0]
        return None

    @property
    def jobs(self):
        """
        List of the jobs.
        """
        return self._jobs

    def end_job(self, job):
        self._last_cpu = self.cpu
        if self.followed_by:
            self.followed_by.create_job(job)

        if len(self._activations_fifo) > 0:
            self._activations_fifo.popleft()
        if len(self._activations_fifo) > 0:
            self.job = self._activations_fifo[0]
            self.sim.activate(self.job, self.job.activate_job())

    def _job_killer(self, job):
        if job.end_date is None and job.computation_time < job.wcet:
            if self._task_info.abort_on_miss:
                self.cancel(job)
                job.abort()

    def create_job(self, pred=None):
        """
        Create a new job from this task. This should probably not be used
        directly by a scheduler.
        """
        self._job_count += 1
        job = Job(self, "{}_{}".format(self.name, self._job_count), pred,
                  monitor=self._monitor, etm=self._etm, sim=self.sim)

        if len(self._activations_fifo) == 0:
            self.job = job
            self.sim.activate(job, job.activate_job())
        self._activations_fifo.append(job)
        self._jobs.append(job)

        timer_deadline = Timer(self.sim, GenericTask._job_killer,
                               (self, job), self.deadline)
        timer_deadline.start()

    def _init(self):
        if self.cpu is None:
            self.cpu = self._sim.processors[0]


class ATask(GenericTask):
    """
    Non-periodic Task process. Inherits from :class:`GenericTask`. The job is
    created by another task.
    """
    fields = ['deadline', 'wcet', 'my_parameter']

    def execute(self):
        self._init()
        yield passivate, self
 

class PTask(GenericTask):
    """
    Periodic Task process. Inherits from :class:`GenericTask`. The jobs are
    created periodically.
    """
    fields = ['activation_date', 'period', 'deadline', 'wcet', 'my_parameter']

    def execute(self):
        self._init()
        # wait the activation date.
        yield hold, self, int(self._task_info.activation_date *
                              self._sim.cycles_per_ms)

        while True:
            #print self.sim.now(), "activate", self.name
            self.create_job()
            yield hold, self, int(self.period * self._sim.cycles_per_ms)
    
 

class SporadicTask(GenericTask):
    """
    Sporadic Task process. Inherits from :class:`GenericTask`. The jobs are
    created using a list of activation dates.
    """
    fields = ['list_activation_dates', 'deadline', 'wcet', 'my_parameter']

    def execute(self):

        self._init()
        for ndate in self.list_activation_dates:
            yield hold, self, int(ndate * self._sim.cycles_per_ms) \
                - self._sim.now()
            self.create_job()

    @property
    def list_activation_dates(self):
        return self._task_info.list_activation_dates



task_types = {
    "Periodic": PTask,
    "APeriodic": ATask,
    "Sporadic": SporadicTask
}

task_types_names = ["Periodic", "APeriodic", "Sporadic"]


def Task(sim, task_info):
    """
    Task factory. Return and instantiate the correct class according to the
    task_info.
    """

    return task_types[task_info.task_type](sim, task_info)

(Jun-24-2019, 05:40 PM)nilamo Wrote:
https://github.com/MaximeCheramy/simso/b...sk.py#L170 Wrote:
    @property
    def deadline(self):
        """
        Deadline in milliseconds.
        """
        return self._task_info.deadline

Are you modifying a library or something? Can you share your whole class, and how you're trying to use it?

Yes. I tried to modify a library. At line 184 I added the setter.
And in another file, on an instance of the class PTask, which I called "task", I tried to set its deadline.

# coding=utf-8

from collections import deque
from SimPy.Simulation import Process, Monitor, hold, passivate
from simso.core.Job import Job
from simso.core.Timer import Timer
from simso.core.CSDP import CSDP

import os
import os.path


class TaskInfo(object):
    """
    TaskInfo is mainly a container class grouping the data that characterize
    a Task. A list of TaskInfo objects are passed to the Model so that
    :class:`Task` instances can be created.
    """

    def __init__(self, name, identifier, task_type, abort_on_miss, period,
                 activation_date, n_instr, mix, stack_file, wcet, acet,
                 et_stddev, deadline, base_cpi, followed_by,
                 list_activation_dates, preemption_cost, data, my_parameter):
        """
        :type name: str
        :type identifier: int
        :type task_type: str
        :type abort_on_miss: bool
        :type period: float
        :type activation_date: float
        :type n_instr: int
        :type mix: float
        :type stack_file: str
        :type wcet: float
        :type acet: float
        :type et_stddev: float
        :type deadline: float
        :type base_cpi: float
        :type followed_by: int
        :type list_activation_dates: list
        :type preemption_cost: int
        :type data: dict
        :type my_parameter: float
        """
        self.name = name
        self.identifier = identifier
        self.task_type = task_type
        self.period = period
        self.activation_date = activation_date
        self.n_instr = n_instr
        self.mix = mix
        self.wcet = wcet
        self.acet = acet
        self.et_stddev = et_stddev
        self.base_cpi = base_cpi
        self._stack = None
        self._csdp = None
        self._stack_file = ''
        self.set_stack_file(*stack_file)
        self.deadline = deadline
        self.followed_by = followed_by
        self.abort_on_miss = abort_on_miss
        self.list_activation_dates = list_activation_dates
        self.data = data
        self.preemption_cost = preemption_cost
        self.my_parameter = my_parameter

    @property
    def csdp(self):
        """
        Accumulated Stack Distance Profile. Used by the cache models instead of
        the Stack Distance Profile for optimization matters.
        """
        return self._csdp

    @property
    def stack_file(self):
        """
        Stack distance profile input file.
        """
        return self._stack_file

    def set_stack_file(self, stack_file, cur_dir):
        """
        Set the stack distance profile.
        """
        if stack_file:
            try:
                self._stack = TaskInfo._parse_stack(stack_file)
                self._csdp = CSDP(self._stack)
                self._stack_file = os.path.relpath(stack_file, cur_dir)
            except Exception as e:
                print("set_stack_file failed:", e)

    @staticmethod
    def _parse_stack(stack_file):
        stack = {}
        if stack_file and os.path.isfile(stack_file):
            for line in open(stack_file):
                dist, value = line.split()
                stack[int(dist)] = float(value)
        else:
            stack = None
        return stack


class GenericTask(Process):
    """
    Abstract class for Tasks. :class:`ATask` and :class:`PTask` inherits from
    this class.

    These classes simulate the behavior of the simulated task. It controls the
    release of the jobs and is able to abort the jobs that exceed their
    deadline.

    The majority of the task_info attributes are available through this class
    too. A set of metrics such as the number of preemptions and migrations are
    available for analysis.
    """
    fields = []

    def __init__(self, sim, task_info):
        """
        Args:

        - `sim`: :class:`Model <simso.core.Model>` instance.
        - `task_info`: A :class:`TaskInfo` representing the Task.

        :type sim: Model
        :type task_info: TaskInfo
        """
        Process.__init__(self, name=task_info.name, sim=sim)
        self.name = task_info.name
        self._task_info = task_info
        self._monitor = Monitor(name="Monitor" + self.name + "_states",
                                sim=sim)
        self._activations_fifo = deque([])
        self._sim = sim
        self.cpu = None
        self._etm = sim.etm
        self._job_count = 0
        self._last_cpu = None
        self._cpi_alone = {}
        self._jobs = []
        self.job = None
        
        

    def __lt__(self, other):
        return self.identifier < other.identifier

    def is_active(self):
        return self.job is not None and self.job.is_active()

    def set_cpi_alone(self, proc, cpi):
        self._cpi_alone[proc] = cpi

    def get_cpi_alone(self, proc=None):
        if proc is None:
            proc = self.cpu
        return self._cpi_alone[proc]

    @property
    def base_cpi(self):
        return self._task_info.base_cpi

    @property
    def data(self):
        """
        Extra data to characterize the task. Only used by the scheduler.
        """
        return self._task_info.data

    @property
    def deadline(self):
        """
        Deadline in milliseconds.
        """
        return self._task_info.deadline
    
    #Added
    @deadline.setter
    def deadline(self, value):
        self._task_info.deadline = value
    

    

    @property
    def n_instr(self):
        return self._task_info.n_instr

    @property
    def mix(self):
        return self._task_info.mix

    @property
    def csdp(self):
        return self._task_info.csdp

    @property
    def preemption_cost(self):
        return self._task_info.preemption_cost

    @property
    def footprint(self):
        return int(self._task_info.n_instr * self._task_info.mix *
                   (1 - self._task_info.csdp.get(-1)))

    @property
    def wcet(self):
        """Worst-Case Execution Time in milliseconds."""
        return self._task_info.wcet
    #Added
    @wcet.setter
    def set_wcet(self, value):
        'setting'
        self._task_info.wcet = value


    @property
    def acet(self):
        return self._task_info.acet
    
    @property
    def my_parameter(self):
        return self._task_info.my_parameter

    @property
    def et_stddev(self):
        return self._task_info.et_stddev

    @property
    def period(self):
        """
        Period of the task.
        """
        return self._task_info.period

    #Added
    @period.setter
    def period(self,value):
        'setting'
        self._task_info.period = value


    @property
    def identifier(self):
        """
        Identifier of the task.
        """
        return self._task_info.identifier

    @property
    def monitor(self):
        """
        The monitor for this Task. Similar to a log mechanism (see Monitor in
        SimPy doc).
        """
        return self._monitor

    @property
    def followed_by(self):
        """
        Task that is activated by the end of a job from this task.
        """
        if self._task_info.followed_by is not None:
            followed = [x for x in self._sim.task_list
                        if (x.identifier == self._task_info.followed_by)]
            if followed:
                return followed[0]
        return None

    @property
    def jobs(self):
        """
        List of the jobs.
        """
        return self._jobs

    def end_job(self, job):
        self._last_cpu = self.cpu
        if self.followed_by:
            self.followed_by.create_job(job)

        if len(self._activations_fifo) > 0:
            self._activations_fifo.popleft()
        if len(self._activations_fifo) > 0:
            self.job = self._activations_fifo[0]
            self.sim.activate(self.job, self.job.activate_job())

    def _job_killer(self, job):
        if job.end_date is None and job.computation_time < job.wcet:
            if self._task_info.abort_on_miss:
                self.cancel(job)
                job.abort()

    def create_job(self, pred=None):
        """
        Create a new job from this task. This should probably not be used
        directly by a scheduler.
        """
        self._job_count += 1
        job = Job(self, "{}_{}".format(self.name, self._job_count), pred,
                  monitor=self._monitor, etm=self._etm, sim=self.sim)

        if len(self._activations_fifo) == 0:
            self.job = job
            self.sim.activate(job, job.activate_job())
        self._activations_fifo.append(job)
        self._jobs.append(job)

        timer_deadline = Timer(self.sim, GenericTask._job_killer,
                               (self, job), self.deadline)
        timer_deadline.start()

    def _init(self):
        if self.cpu is None:
            self.cpu = self._sim.processors[0]


class ATask(GenericTask):
    """
    Non-periodic Task process. Inherits from :class:`GenericTask`. The job is
    created by another task.
    """
    fields = ['deadline', 'wcet', 'my_parameter']

    def execute(self):
        self._init()
        yield passivate, self
 

class PTask(GenericTask):
    """
    Periodic Task process. Inherits from :class:`GenericTask`. The jobs are
    created periodically.
    """
    fields = ['activation_date', 'period', 'deadline', 'wcet', 'my_parameter']

    def execute(self):
        self._init()
        # wait the activation date.
        yield hold, self, int(self._task_info.activation_date *
                              self._sim.cycles_per_ms)

        while True:
            #print self.sim.now(), "activate", self.name
            self.create_job()
            yield hold, self, int(self.period * self._sim.cycles_per_ms)
    
 

class SporadicTask(GenericTask):
    """
    Sporadic Task process. Inherits from :class:`GenericTask`. The jobs are
    created using a list of activation dates.
    """
    fields = ['list_activation_dates', 'deadline', 'wcet', 'my_parameter']

    def execute(self):

        self._init()
        for ndate in self.list_activation_dates:
            yield hold, self, int(ndate * self._sim.cycles_per_ms) \
                - self._sim.now()
            self.create_job()

    @property
    def list_activation_dates(self):
        return self._task_info.list_activation_dates



task_types = {
    "Periodic": PTask,
    "APeriodic": ATask,
    "Sporadic": SporadicTask
}

task_types_names = ["Periodic", "APeriodic", "Sporadic"]


def Task(sim, task_info):
    """
    Task factory. Return and instantiate the correct class according to the
    task_info.
    """

    return task_types[task_info.task_type](sim, task_info)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Error: audioio has no attribute 'AudioOut' netwrok 3 644 Oct-22-2023, 05:53 PM
Last Post: netwrok
  cx_oracle Error - AttributeError: 'function' object has no attribute 'cursor' birajdarmm 1 2,367 Apr-15-2023, 05:17 PM
Last Post: deanhystad
  Getting 'NoneType' object has no attribute 'find' error when WebScraping with BS Franky77 2 5,269 Aug-17-2021, 05:24 PM
Last Post: Franky77
  Attribute Error received not understood (Please Help) crocolicious 5 2,688 Jun-19-2021, 08:45 PM
Last Post: crocolicious
  error in scapy attribute 'haslayer' evilcode1 5 6,541 Mar-02-2021, 11:19 AM
Last Post: evilcode1
  attribute error instead of correct output MaartenRo 2 2,196 Aug-28-2020, 10:22 AM
Last Post: Larz60+
  attribute error stumped on how to fix it. hank4eva 7 4,751 Aug-11-2020, 04:47 AM
Last Post: hank4eva
  Attribute Error - trying to create a pixel array out of PNG files The_Sarco 1 2,008 Apr-29-2020, 07:10 PM
Last Post: deanhystad
  Attribute Error for Rename / Replace warden89 6 7,857 Jan-07-2020, 06:08 PM
Last Post: warden89
  Reading DBF files from Amazon s3 throwing error - 'int' object has no attribute 'isa abeesm 1 2,918 Sep-22-2019, 05:49 PM
Last Post: ndc85430

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020