Poset is a function, which constructs a finite poset, not the poset class, as you can check:
sage: type(Poset)
<class 'function'>
You can also check it by having a look at the source code:
sage: Poset??
So when you write
Poset.upper_bounds = upper_bounds
you are attaching upper_bounds to the function, not to the class of posets. The latter is FinitePoset (actually a subclass of it, name FinitePoset_with_category, which is constructed dynamically via Sage category mechanism). So you should do
sage: from sage.combinat.posets.posets import FinitePoset
sage: FinitePoset.upper_bounds = upper_bounds
Then
sage: X = Poset(...)
sage: X.upper_bounds(...)
shoud work.